B. Fitzgerald
B. Fitzgerald

Reputation: 135

How to change formatting of Html.DisplayFor for a user-defined class in MVC

My main model, Project, has a property called "ProjectAddress" which is of type "Address"--a class that I defined. Address has the properties Line1, Line2, City, State, and ZipCode. When I use @Html.DisplayFor(model => model.ProjectAddress), it displays as:

Line 1
<Line1 value here>
Line 2
<Line2 value here>
City
<City value here>
...

and so on. I would like it to display as:

<Line 1>
<Line 2 if defined>
<City>, <State>, <ZipCode>
<County> County

without the property headers above each value. I can do this manually each time I want to display the address by hard coding

@Html.DisplayFor(model => model.ProjectAddress.Line1)
@if (!String.IsEmptyOrNull(model.ProjectAddress.Line2))
{
    @Html.DisplayFor(model => model.ProjectAddress.Line2)
}
@Html.DisplayFor(model => model.ProjectAddress.City), @Html.DisplayFor(model => model.ProjectAddress.State), @Html.DisplayFor(model => model.ProjectAddress.ZipCode)

but that's very tedious and if I change the format of my address class for whatever reason I'll have to go through my code and change each instance of that. Is there a way that I can change the formatting of @Html.DisplayFor(model => model.ProjectAddress) to be the block of code above?

Upvotes: 1

Views: 1068

Answers (2)

Michael Coxon
Michael Coxon

Reputation: 5510

Check out a thing called Display Templates. The short of it is this..

  1. You create a new folder under views/shared called 'DisplayTemplates` (you can also have editor templates.
  2. Add a new cshtml file called Address.cshtml. Set its model to My.LongNamespace.Address
  3. Add the code you want to use to 'mark-up' the address type.

Example Address.cshtml (untested)

@model My.LongNamespace.Address

@Html.DisplayFor(model => model.Line1)
@if (!String.IsEmptyOrNull(model.Line2))
{
    @Html.DisplayFor(model => model.Line2)
}
@Html.DisplayFor(model => model.City), 
@Html.DisplayFor(model => model.State), 
@Html.DisplayFor(model => model.ZipCode)

Upvotes: 1

Chris Pratt
Chris Pratt

Reputation: 239290

You need to add a custom display template. Add the file, Views\Shared\DisplayTemplates\Address.cshtml, and put the following code inside:

@model Namespace.To.Address
@Html.DisplayFor(m => m.Line1)
@if (!String.IsEmptyOrNull(Model.Line2))
{
    @Html.DisplayFor(m => m.Line2)
}
@Html.DisplayFor(m => m.City), @Html.DisplayFor(m => m.State), 
@Html.DisplayFor(m => m.ZipCode)

Then, you can use DisplayFor as you tried originally in your view:

@Html.DisplayFor(m => m.ProjectAddress)

Razor will use the template you defined to render the ProjectAddress instance.

Upvotes: 2

Related Questions