Define a custom HTML prefix for your .NET MVC models

There might be the case when you develop with .NET MVC, that you have to render a complex view which contains a hierarchy of partial views.

In such times you might want to render more than one instances of a ViewModel inside the view or you just want to use different ViewModels, like one from your framework and one from your partial view, that have the same name.

In order to avoid collisions of names of the properties between the models, you can use the HTMLFieldPrefix property which adds a prefix to the CSS id and name attributes.

Let us consider the ViewModel class in the following example:

1
2
3
4
5
6
7
8
public class DemoViewModel
{
    public string Lastname { get; set; }

    public string Firstname { get; set; }

    public int Age { get; set; }
}

We define the following controller action that renders a view which uses the DemoViewModel class. Notice how we assign the name of the prefix into the HtmlFieldPrefix property.

1
2
3
4
5
6
7
[HttpGet]
public ActionResult Demo()
{
    ViewData.TemplateInfo.HtmlFieldPrefix = "CustomPrefix";

    return View();
}

and here we have our view:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@model ExampleMVCPrefixViewModel.Models.DemoViewModel

@{
    ViewBag.Title = "Demo";
}

@using (Html.BeginForm("DemoSubmit", "Home", FormMethod.Post))
{
    @Html.LabelFor(m => m.Lastname)
    @Html.TextBoxFor(m => m.Lastname)

    @Html.LabelFor(m => m.Firstname)
    @Html.TextBoxFor(m => m.Firstname)

    @Html.LabelFor(m => m.Age)
    @Html.TextBoxFor(m => m.Age)
    <input type="submit" value="Submit" />
}

In the following image you can see how the prefix changes the CSS id and name attributes of each of the model properties.

The HtmlFieldPrefix as in gets rendered inside the CSS ids

Now, when we submit the form our ViewModel instance lands into the following controller action:

1
2
3
4
5
6
7
[HttpPost]
public ActionResult DemoSubmit([Bind(Prefix = "CustomPrefix")] DemoViewModel vm)
{
    ViewBag.Message = $"Hello {vm.Firstname} {vm.Firstname}!";

    return View(vm);
}

In order to be able to read the values of the “prefixed” properties, we have to use the [Bind(Prefix)] attribute in the definition of the method. This does the trick of assigning the properties that are prefixed back to an object of type DemoViewModel. The mapping was successful and here you can see the content of the object:

The Bind attribute in action

Hope this will help someone out there :).

comments powered by Disqus