Frage

I am trying to use a display template (Pet.cshtml), which I have placed in ~/Views/Shared/DisplayTemplates, as per convention.

The Index action gets the IEnumerable and passes it to Index.cshtml, which passes it along to _PetTablePartial. So far, so good. However, when Html.DisplayForModel is called, I get this error:

The model item passed into the dictionary is of type 'Pet', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Pet]'. 

But I (think) I can clearly see that the model item is in fact an IEnumerable. What am I doing wrong?

Controller: 

public ActionResult Index()
{
  return View(pet.GetPets()); // returns IEnumerable<Pet>
}

Index.cshtml:

@model IEnumerable<Pet>
{Html.RenderPartial("_PetTablePartial", Model);}
...

_PetTablePartial.cshtml:

@model IEnumerable<Pet>
@Html.DisplayForModel()

~/Shared/DisplayTemplates/Pet.cshtml:
@model IEnumerable<Pet>

<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
...
War es hilfreich?

Lösung

Pet.cshtml should have a model type of Pet, because you are only dealing with a single pet here.

DisplayTemplates automatically enumerate over a collection, and call your DisplayTemplate with a single item. That's one of their benefits. You don't need to do any enumeration.

Just change Pet.cshtml's type to Pet

I also suspect you don't want to have a separate table for each pet. So what you want is to create the table and header In your partial view, then only have a single data row in Pet.cshtml, because Pet.cshtml will be called multiple times, once for each row.

PetTablePartial.cshtml:

@model IEnumerable<Pet>

<table>
    <tr>
        <th> Pet Name </th>
    </tr>
   @Html.DisplayForModel()
</table>

~/Shared/DisplayTemplates/Pet.cshtml:

@model Pet

<tr>
    <td>@Html.DisplayFor(x => x.Name)</td>
</tr>

Andere Tipps

In the Pet.cshtml you are passing in IEnumerable<Pet>, but then trying to access the Name property of the model. IEnumerable does not have a Name property.

In general, you would wrap this with a foreach loop so you can access the Name property of the elements on the list. However, since you are trying to write out the table header, you only want to write it out once and not traverse the list.

Take a look at these other SO questions:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top