Colin Bacon
Colin Bacon

Reputation: 15609

Different behaviour when specifying display template with @Html.DisplayFor

I'm getting an unexpected error when using DisplayFor and specifying the display template to use.

I have a model which implements a base model

public class Smokey : Bacon
{

}

I have a display template for this; Smokey.cshtml which has a model of Smokey

Now the model that I pass to the DisplayFor is IEnumerable<Bacon>. This works fine when I do not specify the display template to use.

@Html.DisplayFor(x => x.Items);

But if I specify the display template I get an exception telling the item passed was IEnumerable of type Bacon but this dictionary requires a model item of type 'Smokey'.

@Html.DisplayFor(x => x.Items, "Smokey");

I'm trying to understand why this works one way and not the other? What is the difference?

Upvotes: 1

Views: 550

Answers (2)

Colin Bacon
Colin Bacon

Reputation: 15609

Solved

The problem turned out to be a limitation of templated helpers. If you specify the template name it no longer applies it to each item in the collection.

The solution to this problem was found in Darin Dimitrov's answer on stackoverflow

Here's the workaround

@for (int i = 0; i < Model.Items.Count(); i++)
{
    @Html.DisplayFor(x => x.Items.ToList()[i], "Smokey")
}

Upvotes: 2

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93424

The reason it doesn't work is because you're telling Razor that you're going to give it Smokey objects, but instead you only give it Bacon objects. Bacon objects are not Smokey objects, but Smokey objects are Bacon objects. It doesn't work the other way around.

The reason it works when you don't include the template is that MVC has a default object template that uses reflection to walk the object and does a DisplayFor() on each public property. This default template is used if it can't find a suitable template.

Upvotes: 1

Related Questions