开发者

How to pass a user's screen name to a view

I want to display the user's screen name in a partial view that is contained in a master page. It is the classic "Log In" / "Welcome John Smith! Log Out" scenario. The user's screen name is different to the User.Identity.Name and requires a database look up, i.e.

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

This is not going to work from within a view - there is no reference to 'appRepository' and views shouldn't really be going around making database calls anyway. How should I set this up so that the screen name is passed to the view from the controller?

All my controllers inherit from a BaseController. I tried setting ViewData["CurrentAppUser.ScreenName"] in the constructor of the of the BaseController class, but at that point the User object is not populated yet. (I am using OpenID with DotNetOpenAuth if that is relevant.) I could set it in every action method on every controller, but that would be supremely ugly.

I also tried setting a session variable when the user logs on, but it seems a use开发者_StackOverflowr can stay logged in even if the session ends. When they come back again they are still logged in, but the session variable is unset.

Any ideas?


I would recommend you using Html.Action. So as always you start by defining a view model:

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

then a controller:

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);
    }
}

a corresponding partial view:

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

finally in your master page (no matter which controller was used to render the view) include the partial:

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

or (Html.RenderPartial which does the same but doesn't return the result but writes it directly to the output stream):

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

A further improvement of this in order to avoid hitting the database on each request for fetching the user screen name would be to cache it somewhere: session, cookie, ...

So no need of base controllers and ViewData. The logic of getting the user screen name is completely separate from the main MVC pipeline and embedded as a widget.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜