ASP.NET Web API正确的方式拥有两种类型的ApplicationUser



我有一个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的操作,这似乎还不够优雅。

我对这项技术还很陌生,还没有探索过它的所有功能,所以我可能错过了一些显而易见的东西。提前谢谢。

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

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...
}

最新更新