My current problem is that I have a partial view that I want to determine what model is being used by it.
I have had to deal with a few strange scenarios for my project so I will try to outline it here, maybe someone can offer a better way to do this.
I am designing something like the Google iGoogle page. A main page with multiple widgets that are able to move around or be configured as needed. The current system loads the actual widget’s data asynchronously view a POST to a controller within my application. That controller will either render a partial view to HTML that can be returned (and then loaded into the page view JQUERY) or just straight HTML/JavaScript that is stored in a database.
This was working fine for me, I had a model for the widgets that holds a dictionary of options that are described via the database, and then used by the partial view. The problem came when I wanted to pass data to a partial view. The best solution I could come up with was having the controller determine which model the partial view in question uses, have some function that will fill the model, and then pass it, along with the partial view, to the function that will render it to HTML within the controller.
I realize this is an odd scenario for MVC (the layers are blending…) and any advice on fundamental design, or implementation of this would be greatly appreciated.
I am currently using MVC3/Razor. Feel free to ask any other questions.
I prototyped a possible solution to this, because it seemed like a fun problem. I hope it’s useful to you.
Models
First, the models. I decided to create two ‘widgets’, one for news, and one for a clock.
Controller
My controller doesn’t know anything about the views. What it does is returns a single model, but that model has the ability to dynamically fetch the right model as required by the view.
Delegates are used so that the correct model is only created/fetched if it is actually used.
ModelSelector
The ModelSelector that the controller uses is pretty simple – it just keeps a bag of delegates to create each model type:
The Views – Simple solution
Now, the easiest way to implement a view would be:
You could end here and use this approach.
The Views – Better solution
That’s pretty ugly. I wanted my views to look like this:
And
To make this work, I had to create a custom view engine.
Custom view engine
When a Razor view is compiled, it inherits a
ViewPage<T>, whereTis the@model. So we can use reflection to figure out what type the view wanted, and select it.The view engine is registered by putting this in Global.asax.cs:
Rendering
My home view includes the following lines to test it all out: