【问题标题】:Extending ASP.NET Identity扩展 ASP.NET 标识
【发布时间】:2014-08-19 23:27:22
【问题描述】:

似乎这个问题已经被问过很多次了,在很多方面,似乎没有一个适合我的确切情况。

这是我的 _LoginPartial.cshtml 文件中的一行:

@Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" })

看到说 User.Identity.GetUserName() 的部分了吗?

我想将其更改为 User.Identity.FirstName 或 User.Identity.GetFirstName()。

我不希望它说“你好电子邮件地址”,而是说“你好 Bob”

我的想法是我只是想在 Identity 类上显示一个新属性(或方法)。显然它必须不止于此。

我添加了 FirstName 属性,并且 它在 AccountController 中可用

public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

它不会暴露在 _LoginPartial 文件中。我希望它暴露在那里!

感谢您的帮助

【问题讨论】:

  • 您可以随时调用数据库 其中 Email 是 User.Identity.GetUserName();

标签: c# asp.net asp.net-mvc asp.net-identity


【解决方案1】:

即使你的答案不是“完全”我想要的,你的 cmets 还是让我找到了这个解决方案:

@using Microsoft.AspNet.Identity
@using YourModelnameHere.Models
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
    @Html.AntiForgeryToken()

    <ul class="nav navbar-nav navbar-right">
        <li>
            @{
                var manager = new UserManager<ApplicationUser>(new Microsoft.AspNet.Identity.EntityFramework.UserStore<ApplicationUser>(new ApplicationDbContext()));
                var currentUser = manager.FindById(User.Identity.GetUserId()); 
            }
            @Html.ActionLink("Hello " + currentUser.FirstName + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" })

            @Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" }) // I no longer need this ActionLink!!!
        </li>
    </ul>
    }
}

在我的 IdentityModel.cs 文件中,我添加了 FirstName 和 LastName 这两个属性

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

【讨论】:

  • 您可以在底部添加@using Microsoft.AspNet.Identity.EntityFramework 以获得更短的代码。很好的答案!
  • 哦,感谢您为我做的工作。不同的是,不想向路过的人显示电子邮件地址。那是登录的一半。
  • 这很有用。在此处添加参考:blogs.msdn.microsoft.com/webdev/2013/10/16/…
  • 我在网上搜索时感到很困惑。我刚刚忘记添加@using MyProj.Models 以访问ApplicationUser。我已经添加了自定义属性!!感谢您的解决方案!
【解决方案2】:

我通过在用户登录时将名字和姓氏添加到声明中来完成此操作,然后编写我自己的扩展方法。

当用户登录时,将您想要的详细信息添加到声明集 (AccountController):

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

    // Add the users primary identity details to the set of claims.
    var pocoForName = GetNameFromSomeWhere();

    identity.AddClaim(new Claim(ClaimTypes.GivenName, pocoForName));

    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

扩展方法,它只是为用户从一组声明中提取详细信息:

public static class IdentityExtensions
{
    public static IdentityName GetGivenName(this IIdentity identity)
    {
        if (identity == null)
            return null;

        return (identity as ClaimsIdentity).FirstOrNull(ClaimTypes.GivenName);
    }

    internal static string FirstOrNull(this ClaimsIdentity identity, string claimType)
    {
        var val = identity.FindFirst(claimType);

        return val == null ? null : val.Value;
    }
}

现在在partial中,只需调用新的扩展方法来获取你想要的细节:

@Html.ActionLink("Hello " + User.Identity.GetGivenName() + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" })

编辑:更新后更接近于 SignInAsync() 方法的原始海报版本

private async Task SignInAsync(ApplicationUser user, bool isPersistent) 
{ 
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);  

    var identity = await user.GenerateUserIdentityAsync(UserManager);
    //add your claim here

    AuthenticationManager.SignIn(new AuthenticationProperties() 
        { 
            IsPersistent = isPersistent 
        }, identity);
}

【讨论】:

  • 感谢您的快速回复。假设我想检索一个已经存在的值,例如 EmailConfirmed?有很大不同吗?
  • 没有。您需要做的就是在 SignInAsync 方法中添加额外的声明(从存储数据的任何地方提取数据),然后创建相应的扩展方法来检索它们。
  • 私有异步任务 SignInAsync(ApplicationUser user, bool isPersistent) { AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, 等待 user.GenerateUserIdentityAsync(UserManager));
  • 感谢您的回复。这对我不起作用——这并不奇怪——根本不怪罪,但我会继续寻找。祝你晚上愉快。
  • 你的SignInAsync在做什么?是你上面发的吗?如果是这样,您没有对身份设置任何声明。
【解决方案3】:

为 Asp .net Core 更新了答案! 希望这可以为其他用户节省一些时间。

@if (SignInManager.IsSignedIn(User)){

<form asp-area="" asp-controller="Account" asp-action="LogOff" method="post" id="logoutForm" class="navbar-right">
    <ul class="nav navbar-nav navbar-right">
        <li>
            @{

                var currentUser = await UserManager.FindByEmailAsync(User.Identity.Name);
            }

            <a asp-area="" asp-controller="Manage" asp-action="Index" title="Manage">Hello @currentUser.FirstName </a>
        </li>
        <li>
            <button type="submit" class="btn btn-link navbar-btn navbar-link">Log off</button>
        </li>
    </ul>
</form>

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 2020-01-27
    相关资源
    最近更新 更多