【问题标题】:ASP.NET Web API correct way to have two types of ApplicationUserASP.NET Web API 正确的方法有两种类型的 ApplicationUser
【发布时间】:2015-11-14 02:57:49
【问题描述】:

我有一个 ASP.NET Web API 应用程序,它有两种类型的用户——客户端和驱动程序。目前,我在客户端和驱动程序控制器中有用于注册客户端和驱动程序的方法。我意识到做到这一点的正确方法是通过ApplicationUser 类的内置身份验证系统。基本上,整个事情让我感到困惑,因为对于两种用户类型,我都有不同的字段。无论如何,我已经提出了两种可能的解决方案,但是,它们听起来都不是实现目标的正确方法。

1) 继承自ApplicationUser

ApplicationUser.cs

public class ApplicationUser : IdentityUser
{
    [Column(TypeName = "datetime2")]
    public DateTime RegistrationDate { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
        return userIdentity;
    }
}

客户端.cs

public class Client : ApplicationUser
{
}

驱动程序.cs

public class Driver: ApplicationUser
{
    private ICollection<Country> countriesOfOperation;

    public Driver()
    {
        this.countriesOfOperation = new HashSet<Country>();
    }

    [Column(TypeName = "datetime2")]
    public DateTime DateOfBirth { get; set; }

    [MaxLength(250)]
    public string AboutMe { get; set; }

    public Genders Gender { get; set; }

    public virtual ICollection<Country> CountriesOfOperation
    {
        get { return this.countriesOfOperation; }
        set { this.countriesOfOperation = value; }
    }
}

这意味着我必须像这样在 AccountController 中创建注册方法:

[AllowAnonymous]
[Route("Clients/register")]
public async Task<IHttpActionResult> RegisterClient(ClientRegisterBindingModel model)
{
    var user = new Client()
    {
        UserName = model.Email,
        Email = model.Email,
        RegistrationDate = DateTime.Now
    };

    IdentityResult result = await UserManager.CreateAsync(user, model.Password);

    if (!result.Succeeded)
    {
        return GetErrorResult(result);
    }

    return Ok();
}

驱动程序类也是如此。当然,继承重用了 UserName、Email、PasswordHash 等内容,但这也意味着我必须为我添加的每种类型的用户创建类似 register 的方法。这让帐户管理非常痛苦。

2) 通过使用引用 ApplicationUser 的字段将客户端和驱动程序保存在单独的表中

public class Client
{
    public string FirstName { get; set; }

    public ApplicationUser Account { get; set; }
}

这似乎好一点,但要访问客户端的用户名,我必须执行clientInstance.Account.UserName 之类的操作,这似乎仍然不够优雅。

我对这项技术还很陌生,而且我还没有探索过它的所有功能,所以我可能会遗漏一些相当明显的东西。提前致谢。

【问题讨论】:

  • 将客户和司机保持在同一个表中,只是他们有不同的 accountId 可能有一个名为 Group 的列并手动创建它们,将所有客户作为第 1 组,将所有司机作为第 2 组
  • @MethodMan,将它们放在同一个表中不会留下太多未使用的列吗?例如,驱动程序类有 3-4 个客户端没有的字段,这意味着对于客户端行,它们必须为 NULL。
  • 很高兴看到您的数据库布局示例,您可以使用 2 个表并构造一个联接查询,我认为您正在使方法变得比它需要的更难。 . 有很多方法可以剥这只猫的皮
  • @arnaudoff 我认为更好的方法是通过分配适当的角色来区分两种类型的用户。
  • @AndriiTsok 所说的基于角色的身份验证是什么?

标签: c# asp.net asp.net-web-api


【解决方案1】:

只需为所有类型的用户使用一个表。用户注册对所有人都是一样的。创建新用户后,您将在此处添加其他详细信息。

Schema:
int ID
int UserType
nvarchar Details
etc...

Entity:
public class User
{
   public int ID {get;set;}
   public int UserType {get;set;}
   public string Email{get;set;}
   public string Password{get;set;}
   public string Details {get;set;}
}

在注册期间,它们的处理方式相同。创建新用户时,您将添加各种详细信息。

//driver
var user = new User()
{
    Details = {
       TruckID = 5,
       SomeOtherDetails = "Whatever"
    }.ToJson() //fake extention method, just convert to jsons string
};

//client
var user = new User()
{
    Details = {
       ClientNumber = 44
    }.ToJson() 
};

如果以后需要处理这些,只需获取用户,然后根据用户类型将详细信息反序列化为各种类型。

var user = GetSomeuser(1);
var truckID = user.Details.FromJson<DriveDetails>().TruckID; //fake extension method to deserialize json string back to object

public class DriverDetails
{
   pubic int TruckID...
   public string SomeOtherDetails...
}

【讨论】:

  • 答案的第一部分是向您展示您如何“可以”处理它,但不建议这样做。用户应该只是用户,他们以相同的方式注册。如果某种类型的用户需要不同的详细信息,只需像文档数据库一样存储它们,然后根据用户类型将它们反序列化。
  • 基本上,您的想法是为其他详细信息创建一个单独的表并为其设置一个外键?例如,我将具有默认帐户属性的用户 Foo 设置为 ApplicationUser,但也具有用于 ApplicationUser 类型的列和另一列,该列是包含特定类型用户所需的附加列的表的外键?
  • 嗯,这是一种方式,但首选方式是只有一张桌子。所有其他详细信息都将进入该字段的 json 字符串。
  • 我已经更新了答案以尝试更好地证明这一点。
  • 任何不需要查询来查找您要查找的行的详细信息都可以一起存储在一个 json 字符串中,并在需要时解析出来。
猜你喜欢
  • 2016-12-04
  • 2020-03-20
  • 1970-01-01
  • 2019-07-18
  • 2019-06-22
  • 1970-01-01
  • 2012-03-29
  • 1970-01-01
  • 2020-05-27
相关资源
最近更新 更多