获取ASP.Net MVC中的当前用户实体

时间:2010-01-02 21:49:40

标签: .net asp.net-mvc authentication

我有这个代码示例:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%
    if (Request.IsAuthenticated) {
%>
        Welcome <b><%= Html.Encode(Page.User.Identity.Name) %></b>!

问题是,我将用户的 ID 放入“用户名”字段中,而不是名称:

User user = _userRepository.Get(...);
FormsAuthentication.RedirectFromLoginPage(user.Id.ToString(), false);

第一个代码示例包含在主视图中,因此会出现在每个视图中。我不明白的是如何将该视图传递给用户模型实体,因为我没有直接调用它。

编辑:在处理HTTP请求时是否只有一点我可以干预将User模型对象注入ViewData?我不想触及每个控制器+动作来实现这一点。

3 个答案:

答案 0 :(得分:1)

最常见的解决方法是将用户存储在会话变量中。我说它也是ASP.NET MVC中最流行的方式。

在实用程序类或自定义页面/ usercontrol基类中:

const string _userSessionKey = "CurrentUser_";
public UserModelType CurrentUser
{
    var user = HttpContext.Current.Session[_userSessionKey] as UserModelType;
    if(user == null)
    {
        if(HttpContext.Current.User.Identity.IsAuthenticated)
        {
            //new UserService() or DependencyContainer.Resolve<IMembershipService>()
            user = new MembershipService().GetUserById(HttpContext.Current.User.Identity.Name);
            HttpContext.Current.Session[_userSessionKey] = user;
        }
    }

    return user;
}

我知道!
这太经典了,可能不是MVC-ish,但通常我看到类似的实现。

保持这个MVC友好的最重要的事情是从控制器更好地调用这个代码。您可以使用输出用户控件的部分控制器(有一个方法RenderAction我认为是最好的部分之一)。因此,视图仅传递用户的名称或不直接调用此用户模型的用户模型。这就是为什么这里的实用程序类比基页/控件类好得多,但总的来说有一些选项。

如果你想要更好的东西,你应该寻找类似的东西:

ASP.Net MVC Membership Starter Kit

答案 1 :(得分:1)

我已经解决的问题是创建一个主视图模型类,几乎每个特定于视图的模型都是从这个类中派生出来的。主模型包含每个视图可能需要的信息。我尝试将这些信息保持在非常小的状态并将其缓存在会话中,以便填充模型不是一个密集的操作。该模型实现了一个接口,以便每个特定于视图的模型也可以实现此接口,因此,如果我只关心基本信息,我可以轻松地创建一个接受接口的强类型视图。我为所有控制器使用基本控制器,并且在基本控制器上实现填充基本模型的代码。每个特定的视图模型都有一个构造函数,它接受基本模型接口并将数据复制到本地实例。

答案 2 :(得分:1)

您可以确保每个控制器/页面/控件都实现一个基类,您可以在其中公开您所追踪的模型数据。

这很快就会变得很痛苦,但传递一个ViewModel比从页面本身击中HttpContext更清晰。

编辑:这是我可能倾向于使用ViewData [“username”]并在MasterPage中使用它的少数情况之一,至少只有基类需要填充此内容,您可以避免整个控制器中的身份验证知识。