Tomas
Tomas

Reputation: 18127

Custom attributes on model

I want to add some custom attributes to the DateTime model property generated by @Html.DisplayForModel, does MVC 4 has something build in?

Just example

I have a model class

public class UserViewModel
    {
        [CustomAttribute( type = "DateTime")]
        public DateTime DateStamp { get; set; }   
    }

Build view like this

@model CA.Website.Models.UserViewModel

@Html.DisplayForModel(Model)

and I would like to get html rendered like this

<div class="display-label">Date Stamp</div>
<div type="DateTime" class="display-field">1/8/2014 12:57:54 PM</div>

Upvotes: 2

Views: 885

Answers (2)

hutchonoid
hutchonoid

Reputation: 33326

You could use UIHint on your model fields like this:

Model:

public class UserViewModel
{
    [UIHint("DateTimeField")]
    public DateTime DateStamp { get; set; }

}

Views/DisplayTemplates DateTimeField.cshtml

@model DateTime
<div class="display-label">Date Stamp</div>
<div type="DateTime" class="display-field">@Model.ToString("dd/MM/yyyy  HH:mm:ss tt")</div>

View

@model UserViewModel
@Html.DisplayFor(m => m.DateStamp)

Update

In answer to the comment, to get it working using @Html.DisplayForModel change your view to this:

@model MvcApplication3.Controllers.HomeController.UserViewModel
@Html.DisplayForModel(Model.DateStamp)

And your DisplayTemplate to this:

@model DateTime
<div type="DateTime" class="display-field">@Model.ToString("dd/MM/yyyy HH:mm:ss tt")</div>

Upvotes: 0

PhilPursglove
PhilPursglove

Reputation: 12589

You don't need an attribute to do this, you can do it with a combination of a DisplayTemplate and the Humanizer library.

Under your Views/Shared folder, add a new folder called DisplayTemplates. Inside it, create a new partial view - I suggest you name it according to the type it will display e.g. DateTime.cshtml.

In the partial, set the model attribute to the type you want to display e.g.

@model DateTime

And then add the markup to show the value e.g.

<div class="display-label">@Html.LabelForModel()</div>
<div type="DateTime" class="display-field">@Model.ToString("dd/MM/yyyy HH:mm:ss")</div>

To use the partial from a parent view, you just use Html.DisplayFor, and the MVC infrastructure does the wiring up for you between the types so that types that have a custom DisplayTemplate use it and everything else uses the default templates.

To get the DateStamp field label to appear as Date Stamp, you've got the option of using the DisplayName attribute (from System.ComponentModel) e.g.

public class UserViewModel
    [DisplayName("Date Stamp")
    public DateTime DateStamp
...

But a more sophisticated approach is to inspect the model you are binding against and pull the property name out of the metadata that MVC uses. This comes from the ViewData.ModelMetadata.PropertyName property, which gets us DateStamp. We can then bring in Humanizer, which has the Humanize extension method for strings which will split out PascalCased strings into separate words, giving us Date Stamp.

<div class="display-label">@Html.ViewData.ModelMetadata.PropertyName.Humanize(LetterCasing.Title)</div>

Upvotes: 1

Related Questions