Modelo de exibição personalizado ASP.NET MVC 3 com UIHint - For Loop necessário?
-
09-09-2020 - |
Pergunta
Se eu tiver um Modelo de visualização assim:
public class MyViewModel
{
[UIHint("SomeTemplate")]
public ICollection<SomeViewModel> Submodel { get; set; }
}
E um fortemente digitado Visualizar com uma linha de HTML como esta:
@Html.DisplayFor(model => model.Submodel)
E um modelo de exibição com uma assinatura como esta:
@model MvcApplication1.Models.SomeViewModel
Recebo um erro dizendo "o item do modelo é do tipo List<SomeViewModel>
mas este dicionário requer um modelo do tipo SomeViewModel
.".
O que faz sentido, mas eu esperava que a inteligência de modelagem integrada do MVC entrasse em ação, veja, é um IEnumerable
de algo e planejo chamar meu modelo N quantidade de vezes, como costuma acontecer para Html.DisplayFor
sem a dica.
Então parece [UIHint]
substitui essa funcionalidade?
Obviamente posso apontar para outro modelo que aceita a coleção e chama Html.DisplayForModel()
, basicamente emulando a inteligência do MVC.Mas espero evitar isso.Honestamente, eu preferiria fazer um loop foreach do que ter aquele modelo "wrapper" de 1 linha.
Alguma ideia melhor?
É como se eu quisesse dizer:"Ei, MVC, crie um modelo para cada um desses caras.Mas em vez de usar a convenção de nomes para encontrar o modelo, aqui vai uma dica".
Solução
UIHint significa "Renderizar este modelo usando o modelo chamado XXX".Então você tem que declarar seu displaytemplate "SomeTemplate" com
@model MvcApplication1.Models.ICollection<SomeViewModel>
E exiba cada item dentro de um foreach.
Outras dicas
Uma alternativa é passar o nome do modelo de string conforme segue
@Html.DisplayFor(model => model.Submodel, "SomeTemplate")
Eu tive o mesmo problema.Parece que o UIHint é ignorado por padrão para tipos complexos.Você pode substituir o comportamento, mas não é simples.Então a solução mais simples seria:
1) Remova a anotação UIHint.2) Em vez disso, certifique-se de que seu arquivo de modelo de exibição seja nomeado como o nome do tipo que você deseja que Html.DisplayFor itere automaticamente.Portanto, no seu caso, nomeie o arquivo do modelo de exibição como SomeViewModel.cshtml.Isso deve funcionar.Não há necessidade de usar explicitamente o loop for.Eu tentei em MVC4 e funciona.
Peguei a solução no seguinte link:http://roysvork.wordpress.com/2012/12/09/dynamic-repeating-field-groups-in-asp-net-mvc-with-just-a-dash-of-knockout-js/