简体   繁体   中英

How to render ModelMetadata object using Html.Displar in Razor-engine in ASP.NET MVC app?

I am trying to utilize the DisplayTemplates feature in razor-engine to automate rendering my display views.

I scan my Model to find the correct ModelMetadata for each property that I want to display. But I am not able to render the properties using Html.DisplayFor correctly.

I tried to display my property like so

// First I find the ModelMetadata for the property
// I call this statement in a loop and each iteration I pass a different PropertyName to get the correct model
ModelMetadata columnMetadata = elementsMetadata.First(x => x.PropertyName == column.PropertyName);

// I attempted to render the columnMetadata object like so
Html.DisplayFor(x => columnMetadata.Model)

The above code works "in term of displaying the correct value" However it does not use the correct DisplayTemplate which is causing the incorrect format.

For example I have an editor template called Currency.cshtml which simply display Model.ToString("C") . I also have another display template called Status.cshtml which accepts boolean value and return "Active" or "Inactive". Both display-template are located in ~/Views/Shared/DisplayTemplates .

But for some reason Html.DisplayFor() isn't looking for the proper template . Here is an example of one of my view-models

public class ViewModel
{
    public string Name { get; set; }

    [DataType(DataType.Currency)]
    public decimal Rate { get; set; }

    [DataType("Status"), DisplayName("Status")]
    public bool Active { get; set; }
}

Currently my view shows a disabled checkbox for the Active property and a non-formatted number for my Rate property.

How can I correctly display ModelMetadata object where the correct display-template is used based on the property data-type?

ModelMetadata contains a DataTypeName property, which contains the value generated by the DataTypeAttribute , which will be "Currency" for your Rate property and "Status" for you Status property. You can use this value in the 2nd argument of DisplayFor()

ModelMetadata columnMetadata = elementsMetadata.First(x => x.PropertyName == column.PropertyName);
string template = columnMetadata.DataTypeName;
Html.DisplayFor(x => columnMetadata.Model, template)

Note also that you can use the UIHintAttribute which also sets the value of DataTypeName , for example

[Display(Name = "Status")] // use this rather that [DisplayName]
[UIHint("Status")]
public bool Active { get; set; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM