如何将用户的屏幕名称传递给视图

时间:2011-05-12 04:59:54

标签: asp.net-mvc openid dotnetopenauth

我想在母版页中包含的局部视图中显示用户的屏幕名称。这是经典的“登录”/“欢迎John Smith!退出”场景。用户的屏幕名称与User.Identity.Name不同,需要查找数据库,即

AppUser currentUser = appRepository.GetAppUser(User.Identity.Name);
string screenName = currentUser.ScreenName;

这不会在视图中起作用 - 没有对'appRepository'的引用,并且视图不应该真正绕过进行数据库调用。我该如何设置它以便将屏幕名称从控制器传递给视图?

我的所有控制器都继承自BaseController。我尝试在ViewData["CurrentAppUser.ScreenName"]类的构造函数中设置BaseController,但此时尚未填充User对象。 (如果相关,我将OpenID与DotNetOpenAuth一起使用。)我可以在每个控制器的每个操作方法中设置它,但这将是非常难看的。

我还尝试在用户登录时设置会话变量,但即使会话结束,用户也似乎可以保持登录状态。当他们再次回来时,他们仍然登录,但会话变量未设置。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

我建议您使用Html.Action。因此,您一如既往地定义视图模型:

public class UserInfoViewModel
{
    public string ScreenName { get; set; }
}

然后是控制器:

public class UserInfoController: Controller
{
    private readonly IUsersRepository _repository;
    public UserInfoController(IUsersRepository repository)
    {
        _repository = repository;
    }

    // Use this attribute if you want to restrict direct access
    // to this action.
    [ChilActionOnly] 
    public ActionResult Index()
    {
        var model = _repository.GetUserInfo(User.Identity.Name);
        return PartialView(model);
    }
}

相应的局部视图:

@model UserInfoViewModel
<div>Hello @Html.DisplayFor(x => x.ScreenName )</div>

最后在您的母版页中(无论使用哪个控制器渲染视图)都包含部分:

@Html.Action("Index", "UserInfo")

或(Html.RenderPartial执行相同操作但不返回结果但直接将其写入输出流中:

@{Html.ActionPartial("Index", "UserInfo");}

为了避免在每次获取用户屏幕名称的请求中访问数据库,对此进行进一步改进将是将其缓存在某处:session,cookie,...

因此不需要基本控制器和ViewData。获取用户屏幕名称的逻辑与主MVC管道完全分离,并作为窗口小部件嵌入。