Dismissile
Dismissile

Reputation: 33071

MVC Master Page Dynamic Data

I have a master page that needs to display some data from my database. As an example, I have a header in the page that will display the number of messages / alerts that a user has. Every single controller is going to need to pass this data to the View. What is the best way to do this in an MVC application. I obviously don't want to copy the code in every controller action.

Upvotes: 1

Views: 666

Answers (3)

TheCloudlessSky
TheCloudlessSky

Reputation: 18353

You could have a model that all models inherit from:

public abstract class MasterModel
{
    public int NumberOfMessages { get; set; }
    public string Username { get; set; }
}

And then you could have some sort of model factory that will create the requested model:

public class ModelFactory : IModelFactory
{

    private IUserRepository userRepository;

    public ModelFactory(IUserRepository userRepository)
    {
         // Inject a repository .. or a service...
         this.userRepository = userRepository;
    }

    public T Create<T>() where T : MasterModel, new()
    {
        var m = new T()
        {
            NumberOfMessages = this.userRepository.GetNumberMessages(currentUser) // Get current user somehow... HttpContext
        };
        return m;

    }
}

So then you'd inject IModelFactory into your controller and then use it inside the action:

[HttpGet]
public ViewResult DoSomething()
{
    var model = this.modelFactory.Create<MyActionModel>();
    return View(model);
}

Then your master has MasterModel model type and then can use this information. This way all your logic could be kept inside a service/repository that is injected into the factory that creates each view's model. This is what I do and it works out great.

Upvotes: 2

Matt Greer
Matt Greer

Reputation: 62027

An alternative to Darin's answer is an ActionFilterAttribute, that plunks the data into every Action's ViewData. Where you place the attribute defines which actions get this. Placing it at a root Controller class means all actions will get it.

Upvotes: 2

Darin Dimitrov
Darin Dimitrov

Reputation: 1038730

You could use child actions. Phil Haack does a great job explaining them in this blog post. This way you would have a specific controller for fetching the data from the repository and passing it to its own partial view. Then in your master page you would simply include the action:

<%= Html.Action("index", "somecontroller") %>

This way other controllers don't need to pass the data to the view. It has a completely separate lifecycle.

Upvotes: 3

Related Questions