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 user 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:
then a controller:
a corresponding partial view:
finally in your master page (no matter which controller was used to render the view) include the partial:
or (
Html.RenderPartialwhich does the same but doesn’t return the result but writes it directly to the output stream):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.