ASP.NET Web API有两种类型的ApplicationUser

时间:2015-11-13 17:36:56

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

我有一个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;
    }
}

Client.cs

public class Client : ApplicationUser
{
}

Driver.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等内容,但这也意味着我必须为我添加的每种类型的用户创建类似寄存器的方法。这使得账户管理变得痛苦。

2)通过引用引用ApplicationUser

的字段,将客户端和驱动程序保存在单独的表中
public class Client
{
    public string FirstName { get; set; }

    public ApplicationUser Account { get; set; }
}

这看起来好一点,但要访问客户端的用户名,我必须做clientInstance.Account.UserName之类的事情,但这看起来还不够优雅。

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

1 个答案:

答案 0 :(得分: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...
}