Anders G. Nordby

Lead Consultant at Itera

Tag Archives: mvc

MVC: Removing Logic from the Partial Views

I far too often see people putting a lot of logic into those of their MVC partial views that are repeated on every page (e.g. the header and the footer). Often, these views are littered with code that is checking whether the user is logged on, reading and/or setting cookies, etc. To keep the partial views short and clean, what I see people do is to just hide this logic away in some helper class. But the code is then still run as part of the view, which I feel logically/semantically/etc is not the right place to do this. The correct place to run such code should be in the controller, but then you’d have to repeat the same code in every controller, right? Nope.

The solution to this is quite simple; just add an abstract base controller that all your controllers inherit, and place the code in its constructor. Create a helper object to hold the necessary information, and pass this along to the view using the ViewBag.

So, your base controller could look something like this:

public abstract class SitePageController<T> : PageController<T> where T: PageData
{
    public SitePageController()
    {
        ViewBag.LoginData = BusinessLogic.GetLoginData(User);
    }
}

Then, as long as all your controllers inherit from SitePageController<T>, the ViewBag.LoginData will be set correctly by all controllers, and can be accessed from all your views. This way, not only do your files looked a bit cleaner, but your code is logically running in the controller layer of the code.

UPDATE:
I was a bit quick to post this; the above code does not work, as the User property is not instantiated at this point in the controller lifecycle. Replace with this code, and it should work just fine:

public abstract class SitePageController<T> : PageController<T> where T: PageData
{
    protected override void OnActionExecuting(ActionExecutingContext ctx)
    {
        base.OnActionExecuting(ctx);
        ViewBag.LoginData = BusinessLogic.GetLoginData(User);
    }
}

Thanx to rob waminal for pointing this out, see reply number 51 here:
accessing HttpContext.Request in a controller’s constructor

Advertisements