C# 关于MVC和身份的两个问题
我对身份和MVC非常陌生,我正在尝试创建一个MVC应用程序,作为我的第一个项目之一 我已经能够遵循并成功地向ApplicationUser:IdentityUser类添加了其他属性C# 关于MVC和身份的两个问题,c#,razor,asp.net-mvc-5,asp.net-identity-2,C#,Razor,Asp.net Mvc 5,Asp.net Identity 2,我对身份和MVC非常陌生,我正在尝试创建一个MVC应用程序,作为我的第一个项目之一 我已经能够遵循并成功地向ApplicationUser:IdentityUser类添加了其他属性 public class ApplicationUser : IdentityUser<string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim> { [Required] [Displa
public class ApplicationUser
: IdentityUser<string, ApplicationUserLogin,
ApplicationUserRole, ApplicationUserClaim>
{
[Required]
[Display(Name = "UserName")]
[StringLength(50)]
public string Handle { get; set; }
[StringLength(100, ErrorMessage = "Your {0} can be at most {1} characters long.")]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[StringLength(100, ErrorMessage = "Your {0} can be at most {1} characters long.")]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[Display(Name = "User Creation Date")]
public DateTime UserCreationDate { get; set; }
public ApplicationUser()
{
this.Id = Guid.NewGuid().ToString();
// Add any custom User properties/code here
}
公共类应用程序用户
:IdentityUser
{
[必需]
[显示(Name=“UserName”)]
[长度(50)]
公共字符串句柄{get;set;}
[StringLength(100,ErrorMessage=“您的{0}最多可以有{1}个字符长。”)]
[显示(Name=“First Name”)]
公共字符串名{get;set;}
[StringLength(100,ErrorMessage=“您的{0}最多可以有{1}个字符长。”)]
[显示(Name=“Last Name”)]
公共字符串LastName{get;set;}
[必需]
[显示(Name=“用户创建日期”)]
公共日期时间UserCreationDate{get;set;}
公共应用程序用户()
{
this.Id=Guid.NewGuid().ToString();
//在此处添加任何自定义用户属性/代码
}
我的问题是:
var manager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
var-manager=newapplicationusermanager(newuserstore
- @ActionLink(“Register”、“Register”、“Account”、routeValue:null、htmlAttributes:new{id=“registerLink”})
- @ActionLink(“登录”、“登录”、“帐户”、routeValue:null、htmlAttributes:new{id=“loginLink”})
UserValidator
继承微软的UserValidator
并处理你的额外字段
更新:
2) 您可以创建自己的扩展方法来获取添加的额外字段
public static string GetSomething(this IIdentity identity)
{
if (identity.IsAuthenticated)
{
var userStore = new UserStore<ApplicationUser>(new Context());
var manager = new UserManager<ApplicationUser>(userStore);
var currentUser = manager.FindById(identity.GetUserId());
return something = currentUser.something;
}
return null;
}
公共静态字符串GetSomething(此IIdentity标识)
{
如果(身份验证)
{
var userStore=newuserstore(newcontext());
var-manager=新的UserManager(userStore);
var currentUser=manager.FindById(identity.GetUserId());
return something=currentUser.something;
}
返回null;
}
实现自定义用户验证程序
已在此处介绍:
与其为每个页面请求点击数据库来显示句柄,不如在登录期间添加声明
定义您自己的索赔:
public static class CustomClaimTypes
{
public const string Handle = "http://schemas.xmlsoap.org/ws/2014/03/mystuff/claims/handle";
}
在登录期间,设置索赔:
private async Task SignInAsync(ApplicationUser user, bool isPersistent, string password = null)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
//Get the handle and add the claim to the identity.
var handle = GetTheHandle();
identity.AddClaim(new Claim(CustomClaimTypes.Handle, handle);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
然后,通过扩展方法,您可以按照与GetUserName()
相同的方式读取它:
最后,你认为:
@User.Identity.GetHandle()
IIdentity
类不会强制转换为ApplicationUser
。这将引发运行时异常。这也是我得到的<代码>无法将类型为“System.Security.Claims.ClaimsIdentity”的对象强制转换为类型为“Foo.Models.ApplicationUser”。ApplicationUser是接口IUser而不是IISER。我现在还没有看到链接这两个链接。为什么你要我将句柄设置为URL?我希望它成为我的ApplicationUser类中的自定义用户名字段设置[Required][Display(Name=“UserName”)][StringLength(50)]公共字符串句柄{get;set;}
我这样做是为了绕过Identity 2.0中链接的用户名/电子邮件,每次尝试断开此链接时,我都会得到无效的登录尝试。
我还尝试实现第一个问题中提到的堆栈溢出文章。我提到资源。当我实现时,我得到的“Microsoft.AspNet.Identity.Resources”由于其保护级别而无法访问。
我理解,因为Microsoft.AspNet.Identity.Resources被标记为受保护的内部而不是公共,所以我真的不理解他是如何在他的代码中使用它的。@shaun只是想澄清一下,这不是将句柄设置为URL。相反,URL是声明类型标识符,如果仔细查看SignInAsync
方法,我们将创建一个claim
实例,该实例使用URL作为声明类型。请参见此处的标准索赔类型:
public static class IdentityExtensions
{
public static string GetHandle(this IIdentity identity)
{
if (identity == null)
return null;
return (identity as ClaimsIdentity).FirstOrNull(CustomClaimTypes.Handle);
}
internal static string FirstOrNull(this ClaimsIdentity identity, string claimType)
{
var val = identity.FindFirst(claimType);
return val == null ? null : val.Value;
}
}
@User.Identity.GetHandle()