Como você lida com a saída de um formulário gerado dinamicamente no ASP.NET MVC?

StackOverflow https://stackoverflow.com/questions/223149

  •  03-07-2019
  •  | 
  •  

Pergunta

Say você cria um formulário usando ASP.NET MVC que tem um número dinâmico de elementos do formulário.

Por exemplo, você precisa de uma caixa de seleção para cada produto, bem como o número de produtos muda de dia para dia.

Como você lidaria com que os dados do formulário que está sendo enviada de volta para o controlador? Você não pode configurar parâmetros no método de ação, porque você não sabe quantos valores do formulário vão voltar.

Foi útil?

Solução

Apenas dar a cada caixa um valor único nome:

<input class="approveCheck" id="<%= "approveCheck" + recordId %>" 
 name="<%= "approveCheck" + recordId %>" type="checkbox" />

Em seguida, analisar a lista de valores do formulário na acção, depois de apresentar:

foreach (var key in Request.Form.Keys)
    {
        string keyString = key.ToString();
        if (keyString.StartsWith("approveCheck", StringComparison.OrdinalIgnoreCase))
        {
            string recNum = keyString.Substring(12, keyString.Length - 12);

            string approvedKey = Request.Form["approveCheck" + recNum];
            bool approved = !String.IsNullOrEmpty(approvedKey);
            // ...

Você não precisa passar valores do formulário como argumentos; você pode simplesmente obtê-los de Request.Form.

Uma outra opção:. Escrever uma fichário de modelo para alterar a lista em um tipo personalizado para o envio do formulário

Outras dicas

A resposta de Per Craig .. que é mais seguro. Existem peculiaridades para postar vários elementos de formulário com o mesmo nome. Eu acrescentaria que seria sábio para quebrar a lógica que faz com que a "coleção" de controles de uma forma semelhante ao WebForms. Web Forms prefixar o nome do controle de recipiente e adiciona um índice. Por exemplo, em um repetidor a elementos de formulário dentro seria nomeado (algo como) RepeaterName_Element1, RepeaterName_Element2. Quando você vai para obter os elementos fora, você tem que usar FindControl ou algo do tipo.

Dependendo das pastas que você está usando, isso deve funcionar:

<%var i = 0;
  foreach (var product (IList<ProductSelection>)ViewData["products"]) {%>
      <%=Html.Hidden(string.Format("products[{0}].Id", i), product.Id)%>
      <%=Html.Checkbox(string.Format("products[{0}].Selected", i))%>
      <%=product.Name%><br/>
<%}%>

... o que resultará em algo HTML como este (aviso a notação de matriz sobre os nomes):

<input name="products[0].Id" type="hidden" value="123">
<input name="products[0].Selected" type="checkbox">
Widget
<input name="products[1].Id" type="hidden" value="987">
<input name="products[1].Selected" type="checkbox">
Gadget

... eo método de controlador que manipula a mensagem:

public ActionResult SelectProducts(IList<ProductSelection> products)
{
     ...
}

Após a ligação, os produtos parâmetro conterá duas instâncias de PRODUCTSELECTION.

Uma ressalva é que eu não usei a nova ligação para objetos complexos padrão. Antes, eu estou usando o NameValueDeserializer ou CastleBind, tanto do Bonfanti. Ambos se comportam desta maneira. Eu estou supondo obrigatório em todos o Beta irá funcionar da mesma forma.

Dependendo de seus dados, você poderia emitir um 'checkboxlist' (que não é possível nas versões mais recentes mais) e usar um parâmetro string[], ou você pode configurar várias formas e apenas modificar a ação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top