3

我正在嘗試擴展最新版本的Visual Studio 2013中的Web API 2(With Individual Accounts)模板中提供的AspNet IdentityRole類。當我點擊/ API /角色它返回一個空數組如何使用Web API擴展IdentityRole 2 + AspNet標識2

身份模型

namespace API.Models 
{ 
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. 
public class ApplicationUser : IdentityUser<string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>, IUser, IUser<string> 
{ 
    [NotMapped] 
    public virtual UserProfile Profile { get; set; } 

    public virtual ICollection<ApplicationUserRole> UserRoles { get; set; } 

    //public virtual List<ApplicationUserRole> ApplicationRoles { get; set; } 

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, 
     string authenticationType) 
    { 
     // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
     ClaimsIdentity userIdentity = await manager.CreateIdentityAsync(this, authenticationType); 
     // Add custom user claims here 
     return userIdentity; 
    } 
} 

public class ApplicationRole : IdentityRole<string, ApplicationUserRole> 
{ 
    public ApplicationRole() : base() { } 

} 

public class ApplicationUserRole : IdentityUserRole<string> 
{ 
    public ApplicationUserRole() 
     : base() 
    { } 

    public virtual ApplicationRole Role { get; set; } 
} 

public class ApplicationDbContext : IdentityDbContext<ApplicationUser,ApplicationRole,string,IdentityUserLogin,ApplicationUserRole,IdentityUserClaim> 

{ 

    public ApplicationDbContext() 
     : base("DefaultConnection") 
    { 
     base.Configuration.ProxyCreationEnabled = false; 
    } 

    public static ApplicationDbContext Create() 
    { 
     return new ApplicationDbContext(); 
    } 
} 

}

身份配置

namespace API 
{ 
// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application. 

public class ApplicationUserManager : UserManager<ApplicationUser, string> 
{ 
    public ApplicationUserManager(IUserStore<ApplicationUser> store) 
     : base(store) 
    { 
    } 

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, 
     IOwinContext context) 
    { 
     var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); 

     // Configure validation logic for usernames 
     manager.UserValidator = new UserValidator<ApplicationUser>(manager) 
     { 
      AllowOnlyAlphanumericUserNames = false, 
      RequireUniqueEmail = true 
     }; 
     // Configure validation logic for passwords 
     manager.PasswordValidator = new PasswordValidator 
     { 
      RequiredLength = 6, 
      RequireNonLetterOrDigit = true, 
      RequireDigit = true, 
      RequireLowercase = true, 
      RequireUppercase = true, 
     }; 
     IDataProtectionProvider dataProtectionProvider = options.DataProtectionProvider; 
     if (dataProtectionProvider != null) 
     { 
      manager.UserTokenProvider = 
       new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity")); 
     } 
     return manager; 
    } 
} 



public class ApplicationRoleManager : RoleManager<ApplicationRole, string> 
{ 
    public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store) 
     : base(store) 
    { 
    } 

    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, 
     IOwinContext context) 
    { 
     var manager = new ApplicationRoleManager(new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>())); 
     return manager; 
    } 

} 

}

+0

出於好奇,你爲什麼要擴展角色類?我發現大多數時候,你真的不需要..你只需要添加項目的索賠。大多數人認爲你必須擴展事物才能獲得更多功能,而這並非總是如此。 – 2014-09-04 21:33:25

+0

我想擴展角色,以便我可以向它們添加一個Permissions對象,並且我想擴展userRoles,以便我可以添加一個虛擬角色對象。現在當我在包含user.Roles的用戶時,它會返回UserRole對象,但是我不能包含UserRole.Role,這樣我就擁有了所有的數據。 – 2014-09-04 21:40:33

+0

爲什麼需要將權限對象添加到角色?角色本質上就是一個標籤。如果你想構建一個複雜的權限系統,我會創建一個將角色映射到權限的UserRole映射對象。我不知道「虛擬角色對象」是什麼意思。我想你會回頭看這個。 – 2014-09-04 21:53:34

回答

8

你錯就錯在這裏

ApplicationDbContext : IdentityDbContext<ApplicationUser> 

你的數據庫上下文是從IdentityDbContext<ApplicationUser> 程度是從

IdentityDbContext<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> 

ApplicationDbContext基地將產生IdentityRole時actualy你想ApplicationRole爲您角色。

您ApplicationDbContext更改爲

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim> 
{ 

public ApplicationDbContext() 
    : base("DefaultConnection", false) 
{ 
    base.Configuration.ProxyCreationEnabled = false; 
} 

public static ApplicationDbContext Create() 
{ 
    return new ApplicationDbContext(); 
} 
} 

你不必在此改變OnModelCreating在這一點上添加屬性的角色。

,因爲你在ApplicationUserRole有導航屬性你應該添加configurationmapping

protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder) 
{ 
    base.OnModelCreating(modelBuilder); 
    modelBuilder.Entity<ApplicationUserRole>().HasRequired(ur => ur.Role).WithMany().HasForeignKey(ur => ur.RoleId); 
} 

IdentityModel.cs應該是這樣的:

public class ApplicationUserRole : IdentityUserRole<string> 
{ 
    public ApplicationUserRole() 
     : base() 
    { } 

    public virtual ApplicationRole Role { get; set; } 
} 

public class ApplicationRole : IdentityRole<string, ApplicationUserRole> 
{ 
    public ApplicationRole() : base() { } 

    public ApplicationRole(string name, string description) 
     : base() 
    { 
     this.Name = name; 
     this.Description = description; 
    } 

    public string Description { get; set; } 
} 

public class ApplicationUser : IdentityUser<string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim> 
{ 
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
    { 
     var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
     return userIdentity; 
    } 
} 

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim> 
{ 

    public ApplicationDbContext() 
     : base("DefaultConnection") 
    { 
     base.Configuration.ProxyCreationEnabled = false; 
    } 

    public static ApplicationDbContext Create() 
    { 
     return new ApplicationDbContext(); 
    } 
    protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     modelBuilder.Entity<ApplicationUserRole>().HasRequired(ur => ur.Role).WithMany().HasForeignKey(ur => ur.RoleId); 
    } 
} 

identityconfig.cs應該是這樣的:

public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>, IUserStore<ApplicationUser> 
{ 
    public ApplicationUserStore(ApplicationDbContext context) 
     : base(context) 
    { 
    } 
} 

public class ApplicationUserManager : UserManager<ApplicationUser> 
{ 
    public ApplicationUserManager(IUserStore<ApplicationUser> store) 
     : base(store) 
    { 
    } 

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    { 
     var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<ApplicationDbContext>())); 
     .... 
    } 
} 
public class ApplicationRoleStore : RoleStore<ApplicationRole, string, ApplicationUserRole> 
{ 
    public ApplicationRoleStore(ApplicationDbContext context) 
     : base(context) 
    { 

    } 
} 
public class ApplicationRoleManager : RoleManager<ApplicationRole, string> 
{ 
    public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store) 
     : base(store) 
    { 
    } 

    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, 
     IOwinContext context) 
    { 
     var manager = new ApplicationRoleManager(new ApplicationRoleStore(context.Get<ApplicationDbContext>())); 
     return manager; 
    } 
} 
+0

當我嘗試這樣做時,我得到以下錯誤(對於用戶和角色):「類型'API.Models.ApplicationRole'不能用作類型參數'TRole'在泛型類型或方法中......沒有從'API.Models.ApplicationRole'到'Microsoft.AspNet.Identity.EntityFramework.IdentityRole 」。 – 2014-09-04 19:58:19

+0

對不起,我忘記了,你必須改變ApplicationRole:IdentityRole 2014-09-04 20:47:52

+0

修復了我的模型頁面,但是現在我的RoleManager和UserManager被吹起來了,具有類似的錯誤(無法將ApplicationRole轉換爲IdentityRole):var manager = new ApplicationRoleManager(new RoleStore (context.Get ())); – 2014-09-04 21:02:58