2016-08-12 74 views
10

在MVC 5中创建一个新项目启动所有必要的类来处理角色和用户,我很好地修改自定义属性。我无法弄清楚的是,在我的情况下,我有多种不同类型的用户,例如主管理员,管理员,作者,供应商和租户。多个独立的注册和登录表单.NET Identity 2.0

所有这些都有不同的属性以及一些共享的属性。通常,我会在各自的数据库表中实现每种类型的用户名&密码。 ASP.NET Identity非常具有吸引力,可以集中存储用户,并且可以通过简单易用的方式管理身份验证,并带有操作结果。

我看了每一个结果从谷歌搜索,但类似我的情况下唯一的解决办法是使用权利(这是据我所知是没有具体作出处理这个具体情况)

我徘徊如果有一种方式asp.net身份支持这种情况?

任何帮助,将不胜感激。谢谢。

+0

我们有类似的情况,一些用户是管理员,其他用户是客户,其他用户是信使和收件人。理赔应该适合您的情况。 –

+0

它是否像所有类型的用户有共同的属性说电子邮件,电话号码和他们自己的具体属性像用户的类型作者有书的名单,但这个属性不需要任何其他用户类型?如果你可以证实这一点,我可以发布在我的项目中实施的解决方案。 –

+0

您的用户是否真的具有不同的类型(例如,有不同的属性来描述每种类型的用户),还是他们在允许在系统中执行的操作中有所不同? –

回答

0

你有两个选择,以满足你的目的:

  1. 使用共享ApplicationUser阶级和Roles授权做的形式 分离。因此,您可以使用RoleManager基于用户的角色创建一个带条件输入的表单(限制在剃刀中使用if(User.IsInRole("UserTypeName"))显示的内容),或者为每个用户类型创建单独的视图并在控制器端对其进行授权。
  2. 使用简单继承来实现基于其 属性的每个用户类型。

,如:

public class CustomUser: ApplicationUser 
{ 
    ... 
} 

你会用鉴别柱端在你AspNetUsers表,这将有助于实体框架的身份应该实例化的行(或CustomUser其中ApplicationUser类)。此后,您可以为正常,或者如果你只想要一个特定类型或另一个,你可以使用OfType<T>像刚才的查询:

var customUsers = db.Users.OfType<CustomUser>(); 

记住您添加到继承类的任何财产,必须nullable您不能要求CustomUser上需要DateTime在数据库级别是必需的,因为它可以防止保存ApplicationUser,而不是该属性。但是,这只是数据库级别的一个问题。您仍然可以使用视图模型在前端视角的CustomUser需要上生成特定属性。

+0

我认为这种方法更好,但请尽可能扩展您的答案,因为我需要在几个小时内给出答案,并希望将来有更多的信息。 –

+0

@KemalEmin你认为很好。我试图加强我的答案。 –

+0

我已经将此标记为答案,因为它为创建应用程序用户提供了更好的灵活性,但是,这篇文章的当前/未来读者应该知道,此刻我在这个主题方面处于相当新手水平,并会在我感受我自己够亲的。否则,请随时发表评论。 –

2

作为索赔的替代品,我会推荐角色。如果你不确定如何做到这一点,请继续阅读。

如果您使用MVC创建了一个默认的Web应用程序,那么实体框架已经安装。假设你已经使用过代码优先迁移,那么EF也会为你设置你的数据库。

在这个过程中,它将添加一个类文件夹Migrations Configuration.cs。这个文件包含一个方法Seed,我们将在其中进行更改。这里

var userStore = new UserStore<ApplicationUser>(context); 
var userManager = new UserManager<ApplicationUser>(userStore); 
userManager.UserValidator = new UserValidator<ApplicationUser>(userManager) { AllowOnlyAlphanumericUserNames = false }; 

一个小秘密:

首先添加以下usings到Configuration.cs:

using Microsoft.AspNet.Identity.EntityFramework; 
using Microsoft.AspNet.Identity; 
using Models; // assuming you have kept to the defaults 

添加以下代码在种子功能。默认情况下,MVC5建立一个基于Email的用户系统。有趣的是,默认情况下,UserManager会检查UserName(与Email相同)是否不包含特殊字符(包括@)。因此需要关闭此功能。

添加一个角色,我们只是做:

context.Roles.AddOrUpdate(r => r.Name, new IdentityRole { Name = "MyRoleName" }); 
context.SaveChanges(); 

要将新用户添加到角色

if (!context.Users.Any(t => t.Email == "[email protected]")) 
{ 
    var user = new ApplicationUser { UserName = "[email protected]", Email = "[email protected]" }; 
    userManager.Create(user, "Password#1"); 
    context.SaveChanges(); 
    userManager.AddToRole(user.Id, "MyRoleName"); 
} 

到现有用户添加到角色:

var existingUser = context.Users.Where(u => u.UserName == "[email protected]").FirstOrDefault(); 
userManager.AddToRoles(existingUser.Id, "MyRoleName"); 

要应用这些更改,只需在包管理器窗口中运行update-database即可。

现在您有角色的用户可以限制任何你喜欢的动作,使用授权属性:

[Authorize(Roles ="MyRoleName")] 

这些属性可以在类级别设置(开启/关闭整个控制器),或为个人行动。要设置多个角色,使用方法:

[Authorize(Roles ="MyRoleName, MyOtherRole")] 

注意,这意味着任何人谁拥有两种角色正式授权。如果你想只授权有两个角色的用户,那么你必须做的:

[Authorize(Roles ="MyRoleName")] 
[Authorize(Roles ="MyOtherRole")] 

除了使用角色来限制访问您的控制器和动作,你也可以用它们来显示在查看/隐藏物品。例如,使用剃须刀:

@if (User.IsInRole("Admin")) 
{ 
    <p><a class="btn btn-danger btn-lg btn-block" href="@Url.Action("Index", "Administration")">Admin Area</a></p> 
} 

这有非管理员的优势,用户不会注意到他们错过了什么!

0

首先我要你创建所有所需的角色如租户等

然后,像RegisterViewModel.cs为管理员,租户等多个独立的注册创建的ViewModels

然后使用操作方法注册控制器AccountController.cs如果您希望用户选择角色,则可以使用此单行

var result = await UserManager.AddToRolesAsync(user.Id, "Tenants"); 

现在使用视图像Register.cshtml来完成过程。

让我code.Create解释ViewModel类Vendor.cs

 public class VendorViewModel 
{ 
    [Required] 
    [EmailAddress] 
    [Display(Name = "Email")] 
    public string Email { get; set; } 

    [Required] 
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 
    [DataType(DataType.Password)] 
    [Display(Name = "Password")] 
    public string Password { get; set; } 

    [DataType(DataType.Password)] 
    [Display(Name = "Confirm password")] 
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 
    public string ConfirmPassword { get; set; }} 

在AccountController.cs现在创建actionmethod供应商

[Authorize(Roles = "Admin")] 
     public async Task<ActionResult> CreateVendor() 
     { 

      return View(); 
     } 
     [Authorize(Roles = "Admin")] 
      [HttpPost] 
public async Task<ActionResult> Vendor(VendorViewModel model) 
     { 
      if (ModelState.IsValid) 
      { 
       var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; 
       var result = await UserManager.CreateAsync(user, model.Password); 
       if (result.Succeeded) 
       { 
     //Add Vendor role to user 
      var role = await UserManager.AddToRolesAsync(user.Id, "Vendor"); 
} 
       AddErrors(result); 
      } 

      // If we got this far, something failed, redisplay form 
      return View(model); 
     } 

现在创建视图Vendor.cshtml

  @model IdentitySample.Models.VendorViewModel 
@{ 
    ViewBag.Title = "Vendor"; 
} 

<h2>@ViewBag.Title.</h2> 

@using (Html.BeginForm("Vendor", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 
{ 
    @Html.AntiForgeryToken() 
    <h4>Create a new account.</h4> 
    <hr /> 
    @Html.ValidationSummary("", new { @class = "text-danger" }) 
    <div class="form-group"> 
     @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 
     <div class="col-md-10"> 
      @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 
     </div> 
    </div> 
    <div class="form-group"> 
     @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 
     <div class="col-md-10"> 
      @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 
     </div> 
    </div> 
    <div class="form-group"> 
     @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 
     <div class="col-md-10"> 
      @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 
     </div> 
    </div> 
    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" class="btn btn-default" value="Vendor" /> 
     </div> 
    </div> 
} 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 

无论何时您需要这些表单,您都可以创建更多类似的内容。

+0

你能否再扩展一下这个答案? –