Nested @ Html.DisplayFor (model => baseClass, "BaseClass") for a base class template not displaying

Several subclasses (such as cheese) share common properties derived from the base class (Product) with properties such as SKU, Name and Description.

To avoid duplication when rendering display / editor templates, I want each subclass template (Cheese.cshtml) to display its unique fields below its common base class template (Product.cshtml).

However, casting from a derived class to a base class (Product)cheese and trying to display its template inside a subclass template has no effect.

DisplayTemplate File Structure:

 .\Views\Shared\DisplayTemplates .\Product.cshtml -- renders common base class fields .\Cheese.cshtml -- renders unique class fields and calls Product.cshtml 

Cheese.chtml :

 @model Application.Data.Models.Cheese @{ var product = (Application.Data.Models.Part)Model; } Base Product Fields: @Html.DisplayFor(x => products, "Product") @* no effect! *@ <div class="field"> <div class="display-label">@Html.LabelFor(m => Model.UniqueProperty)</div> <div class="display-field">@Html.DisplayFor(m => Model.UniqueProperty)</div> </div> 

Casting to the base class and rendering the Product.cshtml template works fine from the view, but not from the subclass template.

How can I display a generic template for my base class from my subclass templates?

+8
templates nested asp.net-mvc-3 razor
source share
2 answers

Solution found

@Html.DisplayFor(...) cannot be nested , so you should use @Html.Partial in your derived template like this:

 @Html.Partial("~/Views/Shared/DisplayTemplates/Product.cshtml", product) %> 

Or, if your file structure allows this, a more complicated way:

 @Html.Partial("DisplayTemplates/Product", product) 
+8
source share

It can be debatable if it is a good idea to pattern complex objects, or if my approach to nested patterns is hack or not. The advantage of this is that in one template, the parent and child can have templates, and not select / use partial views.

All that aside, template views can be nested if you use a partial view as a transition between them.

The external template will have something like below where you want to place the internal template:

 Html.RenderPartial("SharedDisplayGoBetweenForFoo", item); 

A general partial view will look like this:

 @model Foo @Html.DisplayFor(a => a); 

Then the internal template will be called and will look like any other.

So your example will look like

Cheese.cshtml:

 @model Application.Data.Models.Cheese @{ var product = (Application.Data.Models.Part)Model; } Base Product Fields: @Html.DisplayFor(x => products, "Product") @* no effect! *@ <div class="field"> <div class="display-label">@Html.LabelFor(m => m.UniqueProperty)</div> <div class="display-field">@Html.RenderPartial("SharedPartialProductGobetween", Model.UniqueProperty)</div> </div> 

SharedPartialProductGobetween.cshtml:

 @model Product @Html.DisplayFor(a => a); 

Your product template will not change.

+1
source share

All Articles