Estou usando um modelo que contém uma lista como propriedade. Estou preenchendo esta lista com itens que peguei do SQL Server. Quero que a lista seja ocultada na visualização e passada para a ação POST. Posteriormente, posso querer adicionar mais itens a esta Lista com jQuery, o que torna um array inadequado para expansão posterior. Normalmente você usaria
@Html.HiddenFor(model => model.MyList)
para realizar essa funcionalidade, mas por algum motivo a Lista no POST é sempre nula.
Pergunta muito simples, alguém sabe por que MVC se comporta assim?
c#
asp.net
asp.net-mvc-3
hidden-field
Anton Smith
fonte
fonte
<input />
s?MyList
contém?HiddenFor
é usado apenas para uma entrada de cada vez.Model.MyList
? Pode ser necessário executar alguma serialização / desserialização em sua lista manualmente.Respostas:
Acabei de encontrar esse problema e resolvi-o simplesmente fazendo o seguinte:
Usando um for em vez de um foreach, a vinculação do modelo funcionará corretamente e coletará todos os seus valores ocultos na lista. Parece a maneira mais simples de resolver esse problema.
fonte
@Html.HiddenFor(model => Model.ToGroups[i].RowId)
@Html.EditorFor(model => Model.ToGroups[i].Id)
seguido por@Html.EditorFor(model => Model.ToGroups[i].Description)
na próxima vez - ambos no loop for. E o controlador conseguiu mapeá-lo para uma lista de modelos com esses campos. E para garantir que nada disso apareça na tela, basta envolvê-lo em<div style="display: none;"></div>
for
-loop para este:for(int i = 0; i < Model.Departments.Count(); i++)
HiddenFor não é como DisplayFor ou EditorFor. Não funcionará com coleções, apenas valores únicos.
Você pode usar o auxiliar Serialize HTML disponível no projeto MVC Futures para serializar um objeto para um campo Oculto ou terá que escrever o código você mesmo. Uma solução melhor é simplesmente serializar um ID de algum tipo e recuperar os dados do banco de dados no postback.
fonte
É um pouco de um truque, mas se
@Html.EditorFor
ou@Html.DisplayFor
trabalho para a sua lista, se você quer ter certeza que é enviado na solicitação post, mas não visível, você pode simplesmente estilo para usardisplay: none;
para escondê-lo em vez disso, por exemplo:fonte
Que tal usar o Newtonsoft para desserializar o objeto em uma string json e, em seguida, inserir isso em seu campo Hidden, por exemplo ( Model.DataResponse.Entity.Commission é uma lista de objetos "CommissionRange" simples como você verá no JSON)
Renderiza como:
No meu caso, faço algumas coisas em JS para editar o json no campo oculto antes de postar de volta
Em meu controlador, uso o Newtonsoft novamente para desserializar:
fonte
Html.HiddenFor
é projetado para apenas um valor. Você precisará serializar sua lista de alguma forma antes de criar o campo oculto.Por exemplo, se sua lista for do tipo string, você pode juntar a lista em uma lista separada por vírgulas e, em seguida, dividir a lista após postar de volta em seu controlador.
fonte
Acabei de descobrir (depois de algumas horas tentando descobrir por que os valores do modelo não estavam voltando para o controlador) que oculto para deve seguir o EditorFor.
A menos que eu esteja fazendo algo errado, foi isso que descobri. Não cometerei o erro de novo.
No contexto de um modelo que contém uma lista de outra classe.
Isso NÃO vai funcionar:
Onde assim VAI ......
fonte
Comecei a vasculhar o código-fonte de
HiddenFor
, e acho que o obstáculo que você está vendo é que seu objeto complexoMyList
não é implicitamente conversível em tipostring
, portanto, a estrutura trata seuModel
valor comonull
e torna ovalue
atributo vazio.fonte
Você pode dar uma olhada nesta solução .
Coloque apenas HiddenFor dentro do EditorTemplate.
E em sua visão coloque isto:
@Html.EditorFor(model => model.MyList)
Deve funcionar.
fonte
Enfrentou o mesmo problema. Sem o loop for, ele postou apenas o primeiro elemento da lista. Depois de iterar pelo loop for, ele pode manter a lista completa e postar com sucesso.
fonte
Outra opção seria:
fonte
O
foreach
loop em vez de umfor
loop pode ser uma solução ligeiramente mais limpa.fonte
Outra maneira possível de corrigir isso seria dar a cada objeto em sua lista um ID e, em seguida, usar
@Html.DropDownListFor(model => model.IDs)
e preencher uma matriz que contém os IDs.fonte
talvez tarde, mas criei um método de extensão para campos ocultos da coleção (com itens de tipo de dados simples):
Então aqui está:
O uso é tão simples quanto:
fonte