ASP.NET MVC 3 Custom Display Template With UIHint

2019-03-19 12:33发布

问题:

If i have a ViewModel like this:

public class MyViewModel
{
   [UIHint("SomeTemplate")]
   public ICollection<SomeViewModel> Submodel { get; set; }
}

And a strongly-typed View with a line of HTML like this:

@Html.DisplayFor(model => model.Submodel)

And a display template with a signature like this:

@model MvcApplication1.Models.SomeViewModel

I get an error saying "the model item is of type List<SomeViewModel> but this dictionary requires a model of type SomeViewModel.".

Which makes sense, but i would have hoped the built-in templating smarts of MVC would kick in, see it's a IEnumerable of something and work out to call my template N amount of times, like how it usually does for Html.DisplayFor without the hint.

So it looks like [UIHint] overrides that functionality?

Obviously i can point to another template which accepts the collection, and calls Html.DisplayForModel(), basically emulating MVC smarts. But i am hoping to avoid that. Honestly i would rather do a foreach loop than having that 1 line "wrapper" template.

Any better ideas?

It's like i want to say: "Hey MVC, render out a template for each one of these guys. But instead of using name-convention to find the template, here's a hint".

回答1:

UIHint means "Render this model using the template named XXX". So you have to declare your displaytemplate "SomeTemplate" with

@model MvcApplication1.Models.ICollection<SomeViewModel>

And display each item inside a foreach.



回答2:

An alternative is to pass the string template name as follow

@Html.DisplayFor(model => model.Submodel, "SomeTemplate")


回答3:

I ran into the same problem. It looks like UIHint is ignored by default for complex types. You can override the behavior but it is not straightforward. So the simpler solution would be:

1) Remove the UIHint annotation. 2) Instead make sure your display template file is named as the type name you want the Html.DisplayFor to automatically iterate over. So in your case, name the display template file as SomeViewModel.cshtml. This should work. There is no need to explicitly use the for loop. I have tried it in MVC4 and it works.

I got the solution from the following link: http://roysvork.wordpress.com/2012/12/09/dynamic-repeating-field-groups-in-asp-net-mvc-with-just-a-dash-of-knockout-js/