Strongly typed views are very useful in MVC for rendering model data on page and binding the properties with the input fields. Moreover, strongly typed views give intellisense support, so that we can choose the right property name for the control. No doubt, statically typed languages are of big advantages. But with .NET 4.0, supports have been provided to dynamically define the types. One of the features is ExpandoObject. Through ExpandoObject, we can create an instance at run-time by adding properties to it.
ExpandoObject can be initialized by:
dynamic expando = new ExpandoObject();
dynamic keyword (Introduced .NET 4.0) are used for initializing variables whose types are late bounded. This is different from var keyword (Introduced .NET 3.0) where we know the type at compile time.
The ExpandoObject class is a part of System.Dynamic namespace. Internally it uses IDictionary<String, Object> for managing contents. More about expandoObjects can be found on this site.
There can be scenarios where we would require dynamic models for view. For example, a view having fields which cannot be bound to any predefined class.
First of all I created expandoObject and dynamically added properties in it as:
In the Action Method, I created the expandoObject and added three fields to be rendered on view along with their values. I passed this dynamic model to View.
Creating dynamically typed views
On the view I declared model type of page as dynamic-
You will notice that I have not used extension with signature @Html.TextBoxFor(m=>m.Physics) but used @Html.TextBox(name,value). This is because Lambda expressions do not support dynamic objects.
The value of marks which was added in model has been rendered on screen for Alice. (Please note that this marks has nothing to do with my marks during college days)
Example usage of dynamic models
There can be many scenarios where we can use dynamically typed views and dynamic models. One situation where it may be useful is in generating dynamic forms. Suppose we are having different sets of views for different students. They are enrolled in different subjects and for every student set of fields (subjects in our case) are stored in Database. Now we have to create classes at run-time based on these subjects, so that we can make changes in DB directly for assigning or removing the subjects and make corresponding changes in Views (which can also be stored in DB).
List of subjects are coming from Database for the student Bob.
The subjects Bob has taken, as fetched from DB are “Physics”, “Biology”, “Maths”, “Chemistry”, “Zoology”.
Let’s make the corresponding changes in Views or create another View for Poor Bob.(Poor, because I know the burden of extra subjects )
I created fields for every subject for Bob on the view as below:
The displayed form now looks like shown below. Hence, there is no need to stop debugging the solution and the View can be generated for another student by using expandoObject features.
Posting the form to controller
Posting the form for such model will require a super-set class which has properties of all the possible properties in different views. Then views can be posted to controller just like normal form.
I created model for that-
There will be automatic binding of form with model just like it occurs for strongly typed views because default model binder for MVC looks for fields name on the view and binds with appropriate matching property of class. Screenshot below shows model is binding the field value on view.
There may be scenarios where we can’t use any class for even binding the posted values. This is possible in the cases when we have to keep everything dynamic like the Name of fields can be changed too. For example, Maths can be changed to Mathematics.
For these kinds of problems, Custom Model binder will be helpful. We can create a dictionary in our model to receive field value (as FormCollection) and map posted values in dictionary.
There are limitations when using dynamic models, like lack of intellisense support, lack of compile time error check and also lack of support in using it with Lambda Expressions. But few times they are useful in views just like dynamic types are useful at other places.