So as I understand it
Given a view model
public class MyViewModel{
public DateTime Date {get; set;}
public MyClass Class {get; set;}
}
.. a View Views\MyController\MyAction.cshtml
@model MyViewModel
@Html.DisplayForModel()
.. a partial View Views\Shared\DisplayTemplates\DateTime.chstml
@model DateTime
Some Date
.. another partial View Views\Shared\DisplayTemplates\MyClass.cshtml
@model MyClass
My Class
.. I should get
Date
Some Date
Class
My Class
.. But I just get
Date
Some Date
So it seems DisplayForModel finds DateTime template but not my custom template, even though I am following the conventions of naming it by the type of the property.
Am I missing something. I am using MVC 3 and believe this feature was already available in MVC 2
Having perused the MVC source code, it turns out that this is, in fact, not possible.
The reason is that @Html.DisplayForModel()
attempts to find a template to use for rendering, by:
MyViewModel.cshtml
or MyViewModel.vbhtml
or MyViewModel.ascx
etc, in location ~\Views
, ~\Views[ControllerName]
, ~\Views\DisplayTemplates
, ~\Views\Shared
, ~\Views\Shared\DisplayTemplates
Object
, for which there exists a built-in templateThe object template is designed such that it retrieves all the model's properties, for rendering, from metadata based on the following condition:
metadata.ShowForDisplay
&& metadata.ModelType != typeof(EntityState)
&& !metadata.IsComplexType
&& !templateInfo.Visited(metadata)
Therefore any property that is a complex type will always be excluded. I think the confusion arises from Brad Wilson's post on custom object template, where he creates a custom object template and addresses the issue of Shallow Dive vs Deep Dive. By implementing a custom deep dive object template this will override the built-in object template and complex types can be rendered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With