Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在MVC5中获取当前登录用户的特定字段?_C#_Asp.net Mvc - Fatal编程技术网

C# 如何在MVC5中获取当前登录用户的特定字段?

C# 如何在MVC5中获取当前登录用户的特定字段?,c#,asp.net-mvc,C#,Asp.net Mvc,我有一个使用个人身份验证的MVC5应用程序,当然还有ASP.NET身份验证。重点是我扩展了一个从ApplicationUser继承的模型,它的定义如下: public class NormalUser : ApplicationUser { public string FirstName { get; set; } public string LastName { get; set; } } 所以,重点是,首先我想检查是否有登录用户,如果有,我想获取他/她的名字、姓氏和电子邮件

我有一个使用个人身份验证的MVC5应用程序,当然还有ASP.NET身份验证。重点是我扩展了一个从ApplicationUser继承的模型,它的定义如下:

public class NormalUser : ApplicationUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
所以,重点是,首先我想检查是否有登录用户,如果有,我想获取他/她的名字、姓氏和电子邮件字段。我怎样才能做到呢

我想我需要使用类似的方法来检查是否有登录用户:

if (Request.IsAuthenticated)
{
    ...
}

但是,我如何才能为当前用户获取这些特定字段的值呢?

是的,在Identity中,如果需要其他用户信息,只需从数据库中提取用户,因为这些信息现在都存储在实际的用户对象上

if (Request.IsAuthenticated)
{
    var user = UserManager.FindById(User.Identity.GetUserId());
}
如果
GetUserId
不在
User.Identity
上,请将以下内容添加到您的使用中:

using Microsoft.AspNet.Identity;

在MVC5中,用户数据默认存储在会话中,并根据请求将数据解析为包含用户名(或id)和声明的
ClaimsPrincipal

这是我选择的实现方式,它可能不是最简单的解决方案,但它确实使它易于使用

用法示例:

在控制器中:

public ActionResult Index()
{
    ViewBag.ReverseDisplayName = this.User.LastName + ", " + this.User.FirstName;
}
在视图或_布局中:

@if(User.IsAuthenticated)
{
     <span>@User.DisplayName</span>
}
3。创建新的自定义
主体

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Claims;

public class UserPrincipal : ClaimsPrincipal
{
    public UserPrincipal(ClaimsPrincipal principal)
        : base(principal.Identities)
    {
    }

    public int UserId
    {
        get { return FindFirstValue<int>(ClaimTypes.NameIdentifier); }
    }

    public string UserName
    {
        get { return FindFirstValue<string>(ClaimsIdentity.DefaultNameClaimType); }
    }

    public string Email
    {
        get { return FindFirstValue<string>(ClaimTypes.Email); }
    }

    public string FirstName
    {
        get { return FindFirstValue<string>(ClaimTypes.GivenName); }
    }

    public string LastName
    {
        get { return FindFirstValue<string>(ClaimTypes.Surname); }
    }

    public string DisplayName
    {
        get
        {
            var name = string.Format("{0} {1}", this.FirstName, this.LastName).Trim();
            return name.Length > 0 ? name : this.UserName;
        }
    }

    public IEnumerable<int> Roles
    {
        get { return FindValues<int>(ClaimTypes.Role); }
    }

    private T FindFirstValue<T>(string type)
    {
        return Claims
            .Where(p => p.Type == type)
            .Select(p => (T)Convert.ChangeType(p.Value, typeof(T), CultureInfo.InvariantCulture))
            .FirstOrDefault();
    }

    private IEnumerable<T> FindValues<T>(string type)
    {
        return Claims
            .Where(p => p.Type == type)
            .Select(p => (T)Convert.ChangeType(p.Value, typeof(T), CultureInfo.InvariantCulture))
            .ToList();
    }
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute()); 
    filters.Add(new AppAuthenticationFilterAttribute());
}
5。在
FilterConfig

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Claims;

public class UserPrincipal : ClaimsPrincipal
{
    public UserPrincipal(ClaimsPrincipal principal)
        : base(principal.Identities)
    {
    }

    public int UserId
    {
        get { return FindFirstValue<int>(ClaimTypes.NameIdentifier); }
    }

    public string UserName
    {
        get { return FindFirstValue<string>(ClaimsIdentity.DefaultNameClaimType); }
    }

    public string Email
    {
        get { return FindFirstValue<string>(ClaimTypes.Email); }
    }

    public string FirstName
    {
        get { return FindFirstValue<string>(ClaimTypes.GivenName); }
    }

    public string LastName
    {
        get { return FindFirstValue<string>(ClaimTypes.Surname); }
    }

    public string DisplayName
    {
        get
        {
            var name = string.Format("{0} {1}", this.FirstName, this.LastName).Trim();
            return name.Length > 0 ? name : this.UserName;
        }
    }

    public IEnumerable<int> Roles
    {
        get { return FindValues<int>(ClaimTypes.Role); }
    }

    private T FindFirstValue<T>(string type)
    {
        return Claims
            .Where(p => p.Type == type)
            .Select(p => (T)Convert.ChangeType(p.Value, typeof(T), CultureInfo.InvariantCulture))
            .FirstOrDefault();
    }

    private IEnumerable<T> FindValues<T>(string type)
    {
        return Claims
            .Where(p => p.Type == type)
            .Select(p => (T)Convert.ChangeType(p.Value, typeof(T), CultureInfo.InvariantCulture))
            .ToList();
    }
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute()); 
    filters.Add(new AppAuthenticationFilterAttribute());
}
现在,
主体
被持久化了,我们所要做的就是在控制器和视图中公开它

6。创建控制器基类

public abstract class ControllerBase : Controller
{
    public new UserPrincipal User
    {
        get { return HttpContext.User as UserPrincipal; }
    }
}
7。创建
WebViewPage
基类并修改
web.config
以使用它

public static UserManager<User,int> Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
{
    var manager = new UserManager<User,int>(new UserStore<User,int>(new ApplicationDbContext()))
    {
        ClaimsIdentityFactory = new AppClaimsIdentityFactory()
    };

    // more initialization here

    return manager;
}
using System.Security.Claims;
using System.Web.Mvc;
using System.Web.Mvc.Filters;


public class AppAuthenticationFilterAttribute : ActionFilterAttribute, IAuthenticationFilter
{
    public void OnAuthentication(AuthenticationContext filterContext)
    {
        //This method is responsible for setting and modifying the principle for the current request though the filterContext .
        //Here you can modify the principle or applying some authentication logic.  
        var principal = filterContext.Principal as ClaimsPrincipal;
        if (principal != null && !(principal is UserPrincipal))
        {
            filterContext.Principal = new UserPrincipal(principal);
        }
    }

    public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
    {
        //This method is responsible for validating the current principal and permitting the execution of the current action/request.
        //Here you should validate if the current principle is valid / permitted to invoke the current action. (However I would place this logic to an authorization filter)
        //filterContext.Result = new RedirectToRouteResult("CustomErrorPage",null);
    }
}
public abstract class BaseViewPage : WebViewPage
{
    public virtual new UserPrincipal User
    {
        get { return base.User as UserPrincipal; }
    }

    public bool IsAuthenticated
    {
        get { return base.User.Identity.IsAuthenticated; }
    }
}

public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
{
    public virtual new UserPrincipal User
    {
        get { return base.User as UserPrincipal; }
    }

    public bool IsAuthenticated
    {
        get { return base.User.Identity.IsAuthenticated; }
    }
}
重要


不要在
主体
上存储太多数据,因为这些数据在每次请求时都会来回传递。

你不能使用或实现一些使用
PrincipalContext
@DJKRAZE的代码吗?我不知道。它使用起来非常简单,你可以通过samAccount获得用户名。实际上,有很多例子。。当用户启动页面或站点时,您可以轻松访问该页面或站点information@ett您是否使用基于声明的ASP.NET Identity 2.0?每次需要用户的名字和姓氏时都从数据库中提取数据对我来说效率很低。这对于获取电子邮件来说非常有效,但对于获取FirstName和LastName字段来说则不然。使用上面的方法,我只能得到标准的ApplicationUser字段,而不是我后来添加的字段。那么,当您实例化
UserManager
时,您必须指定要使用的用户类。您可能只是在使用默认值,即
UserManager
,它只返回没有
FirstName
LastName
属性的
ApplicationUser
实例。因此,您可以实例化
UserManager
,也可以通过
context.Users.OfType.Find(User.Identity.GetUserId())
直接使用您的上下文。请注意,这些内容是在我的AccountContoller中定义的,但现在我在我的HomeController中工作。当我执行类似于
ApplicationDbContext db=newapplicationdbcontext()的操作时;var user=db.Users.OfType.Find(user.Identity.GetUserId())
,我在OfType is a method处收到一条错误消息,该消息在给定上下文中无效。如果我使用
UserManager(User.Identity.GetUserId())
,我会收到一条错误消息,UserManager是一个类型,但像变量一样使用。首先,这是我的错。我忽略了后面的括号,即type()的
。关于第二点,您不能直接使用
UserManager
,您需要定义该类型的变量,即
var UserManager=newusermanager(newuserstore())(不是你的错)这是胡说八道MS在想什么?天哪。