0

I appologize if this is a possible duplication, I've looked everywhere and couldn't find an answer.

My question is more of a "best practice/convention"-sort of question.

So here is my situation, I'm having an AccountController -> something like this:

    public AccountController(IAuthenticationHelper authHelper, 
                             IAccountService accountService)
    {
        _authHelper     = authHelper;
        _accountService = accountService;
    }

In my _Layout view, I have a placeholder for the currently logged in account. In order to get the currently logged in account, I'm retrieving the current user identity from the HttpContext (which I have in a wrapper class so I can unit test it) -> then I'm getting the account details from the DB.

Now here is my question, I need this data In the _Layout, I could possibly do a partial view expecting an account model -> place it in the _Layout ... And here is where I get stuck, I don't like the idea of so many trips to the database, and I don't like the fact that I have to think about this small detail from within all Actions ? Am I missing something here, am I thinking of this wrong ? Did I got the concept wrong ? What's the right way to do this ? (In a testable manner, preferably).

Help is much appreciated !

EDIT: I'll be happy to provide with more code, if required.

1
  • How many trips is too many? You would be surprised how many times some popular applications hit the database per request. I usually see "current user logic" encased in a BaseController. Commented Jan 27, 2013 at 14:38

2 Answers 2

2

You could use Child actions to achieve that. For example you will have a specific controller dedicated to retrieving the currently logged user details and pass them to a partial view:

public class UserInfoController: Controller
{
    [ChildActionOnly]
    public ActionResult Index()
    {
        var model = new UserDetailsViewModel();
        if (User.Identity.IsAuthenticated)
        {
            string username = User.Identity.Name;
            // fetch the user info from the database and populate your view model
            // consider caching this information to avoid multiple round-trips 
            // to the database
        }

        return PartialView(model);
    }
}

Then of course you will have a corresponding partial view to display the user information.

And from your _Layout you could render this child action:

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

And of course to avoid multiple roundtrips to the database you could simple cache this information.

Now your main actions and models don't have to worry about this common functionality. It is handled by the child action. Obviously you have the possibility to use Dependency Injection in the UserInfoController to make it perfectly unit testable.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, Darin :) I appreciate your help. I've tried using Html.RenderAction before (didn't try Html.Action - I'm guessing there is big difference), and I've failed for some reason, especially when it came to the view. However the provided solution seems very elegant and is exactly what I'm looking for ! Nazdrave :)
Html.Action and Html.RenderAction are pretty much the same. The syntax is different: @Html.Action("Index", "UserInfo") vs @{Html.RenderAction("Index", "UserInfo");}. The difference is that Html.RenderAction is writing directly to the output stream whereas Html.Action is caching the output to a buffer which is then flushed to the response. Html.RenderAction is a bit faster and consumes less memory for this reason.
1

Typically, after login, I store the relevant account details in the Session. Since the Session is available in all views, you can reference it from there. If you'd prefer, you can also derive from a common view model and have your controllers derive from a custom controller base. You can then use OnActionExecuted to populate the user-related portions of your common view model with the account details, either from the Session or directly from the database.

2 Comments

Thank you for your answer, could you please provide me with a link (if you have one) with more info on the OnActionExecuted way ? Maybe some code examples ? I would certainly like to explore this option more.
@DimitarDimitrov I've got an example of how I handle analytics similarly at farm-fresh-code.blogspot.com/2012/08/analytics-are-aspect.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.