Insights

Accessing MVC view model properties in a loop

 

Accessing MVC view model properties in a loop

Sep 06, 2019

By Rod McBride

With Model–View–Controller (MVC), it’s easy to access the model that’s bound to a view, and then display the various property names and values. The scaffolding feature does just that. However, I wanted to display the property name (or display name) and its value, one property per line, for emailing purposes, so I was looking for a way to loop through the properties. This was so that if the model changed in the future, no changes would be needed in the view.

MVC loop through model in controller

It turns out that the ModelMetadata property of ViewData dictionary object allows you to get or set the information about the model bound to the view.

For example, if I had a model, as shown in Listing 1 below, and a strongly-typed view based on this model (Listing 2), I could then access the ModelMetadata property and simply loop through its properties, as needed.

publicclassSampleEmail

{
    publicstringFrom { getset; }
    publicstringTo { getset; }
    [Display(Name = "Comments")]
    publicstringMessage { getset; }
}

Listing 1. Sample email model

@model ModelLoop.Models.SampleEmail
@{

    ViewData["Title"] = "Details";
}

<h2>ModelMetadata Properties</h2>

<divclass="form-horizontal">
     @foreach(var property inViewData.ModelMetadata.Properties)
    {
        <divclass="form-group">
            @Html.Label(property.GetDisplayName(), new{ @class = "control-label col-md-2"})

            @Html.Editor(property.PropertyName, new{ htmlAttributes = new{ @class = "form-control col-md-2"} })
        </div>
    }
</div>

Listing 2. Sample view

The property.GetDisplayName() method will return either the DisplayName, if it’s not null, or the PropertyName. You can specify the content and HTML controls without the MVC helpers, as needed (Listing 3), and the Bootstrap CSS classes are not needed. 

<labelclass="control-label col-md-2"
for="@property.PropertyName">@(property.GetDisplayName())</label>
<inputclass="form-control col-md-2"id="@property.PropertyName"
name="@property.PropertyName"type="text"value="@property.Model"/>

Listing 3. Html content without the MVC Helpers

The ModelMetadata object contains the metadata about all the properties of the model. So, in the case of the SampleEmail model, there would be three metadata objects: from, to and message. See Figure 2 and Figure 3.

Accessing MVC view model properties in a loop

Figure 2. ModelMetadata property objects

Accessing MVC view model properties in a loop

Figure 3. ModelMetadata property object detail

The ModelMetadata class, which was introduced a while back in MVC2, can be quite handy. See Brad Wilson’s post on ModelMetadata for more information. And if you have any questions about MVC or how to view model properties in a loop, contact Wipfli. You can also read more technology-focused articles here.