Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 3 Custom Templates and EditorForModel confusion

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

like image 923
ricardo Avatar asked Jun 02 '11 13:06

ricardo


1 Answers

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:

  • first looking for the name of the model's type, i.e. MyViewModel.cshtml or MyViewModel.vbhtml or MyViewModel.ascx etc, in location ~\Views, ~\Views[ControllerName], ~\Views\DisplayTemplates, ~\Views\Shared, ~\Views\Shared\DisplayTemplates
  • if it is not found it will walk down the model's base types, attempting each type's name in turn
  • if none are found, it will eventually end up at Object, for which there exists a built-in template

The 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.

like image 187
ricardo Avatar answered Sep 28 '22 10:09

ricardo