tags:

views:

34

answers:

3

How can I provide a user object to every view in ASP.NET MVC without having to create a ViewModel for absolutely every view I have?

When using ASP.NET Membership, I just get a Profile variable in the views with the profile information, but when rolling my own I don't see a way to export that information.

A: 

Inherit your ViewModel classes from a master ViewModel with a User property.

Alternatively, you can pass the object in ViewData collection and use an extension method to make it easy to access the object in the view.

Mehrdad Afshari
I would still have to have ViewModels for all views, in many I can just use a model, in many I don't need any model at all.
J. Pablo Fernández
Using the ViewData would still require every action of my site to fetch the profile data and put it in there, having a lot of repetition, and, a lot of casting on the view, which is horrible.
J. Pablo Fernández
View casts are taken care of by the extension method on the view but the controller will have to fetch on each action.
Mehrdad Afshari
+1  A: 

Inherit your controllers from base controller. In base controller override OnActionExecuting and set ViewData["UserObject"] here. Something like this:

public class YourBaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Controller.ViewData["UserObject"] = ...
    }
}

Or create custom filter with the same OnActionExecuting method if you want only certain controllers providing user object to View.

UPDATED:

Create custom Html helper if you dont want to cast ViewData["UserObject"] every time:

public static object RenderUserObject(this HtmlHelper html)
{
    return ((html.ViewData["UserObject"] as UserObject) ?? new UserObject()).ToString();
}
eu-ge-ne
Don't I then have to cast every time I want to use ViewData["UserObject"]?
J. Pablo Fernández
I've updated my answer
eu-ge-ne
A: 

One alternative to having a base ViewModel class, and so having to define a ViewModel class for every view, is to create a generic ViewModel<T> class which exposes a property T InnerModel, or something similar. Then you can pass a ViewModel<Foo> rather than having to explicitly create a FooViewModel class.

Of course if you also need more bespoke ViewModels in places, you can keep the ViewModel base class, and have ViewModel<T> and your bespoke ViewModels extend it.

stevemegson