Sto tentando di associare un elenco che fa parte di un modello di vista più grande senza ricorrere a un modello di raccoglitore personalizzato. Quando utilizzo un modello di editor per creare l'elenco di input, i nomi generati non sono nel formato corretto affinché il binder predefinito funzioni.ASP.NET MVC Modello Binding IList in un modello di editor
Invece di Articoli [3]. Come mi aspetterei che sia Articoli. [3] .Id. Se creo la lista senza un modello di editor funziona come previsto.
Sto facendo qualcosa ovviamente sbagliato o è solo una stranezza di Html.Hidden e Html.TextBox?
public class ItemWrapper
{
[UIHint("ItemList")]
public IList<Item> Items { get; set; }
}
public class Item
{
public Guid Id { get; set; }
public string Name { get; set; }
public int Value { get; set; }
}
Index.aspx
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Index</h2>
<% using(Html.BeginForm())
{%>
<%:Html.EditorFor(m => m.Items) %>
<%}%>
</asp:Content>
ItemList.ascx
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList<Mvc2Test.Models.Item>>" %>
<h4>Asset Class Allocation</h4>
<% if(Model.Count > 0) { %>
<table>
<tbody>
<% for(int i = 0; i < Model.Count; i++)
{%>
<tr>
<td><%: Model[i].Name%></td>
<td>
<%: Html.HiddenFor(m => m[i].Id) %>
<%: Html.TextBoxFor(m => m[i].Value) %>
</td>
</tr>
<%}%>
</tbody>
</table>
<%
}%>
uscita
<tr>
<td>Item 4</td>
<td>
<input id="Items__3__Id" name="Items.[3].Id" type="hidden" value="f52a1f57-fca8-4bc5-a746-ee0cef4e05c2" />
<input id="Items__3__Value" name="Items.[3].Value" type="text" value="40" />
</td>
</tr>
Modifica (metodo d'azione)
public ActionResult Test()
{
return View(
new ItemWrapper
{
Items = new List<Item>
{
{ new Item { Id = Guid.NewGuid(), Name = "Item 1", Value = 10 } },
{ new Item { Id = Guid.NewGuid(), Name = "Item 2", Value = 20 } },
{ new Item { Id = Guid.NewGuid(), Name = "Item 3", Value = 30 } },
{ new Item { Id = Guid.NewGuid(), Name = "Item 4", Value = 40 } }
}
});
}
Modifica # 2
HttpPost azione
[HttpPost]
public ActionResult Test(ItemWrapper w)
{
if(w.Items == null)
Response.Write("Items was null");
else
Response.Write("Items found " + w.Items.Count.ToString());
return null;
}
Index.aspx
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h4>Does Not Work</h4>
<% using(Html.BeginForm("Test", "Home"))
{%>
<%:Html.EditorFor(m => m.Items) %>
<input type="submit" value-"Go" />
<%}%>
<h4>Does Work</h4>
<% using(Html.BeginForm("Test", "Home"))
{%>
<table>
<tbody>
<% for(int i = 0; i < Model.Items.Count; i++)
{%>
<tr>
<td><%: Model.Items[i].Name%></td>
<td>
<%: Html.HiddenFor(m => Model.Items[i].Id) %>
<%: Html.TextBoxFor(m => Model.Items[i].Value) %>
</td>
</tr>
<%}%>
</tbody>
</table>
<input type="submit" value-"Go" />
<%}%>
</asp:Content>
Quindi è davvero una stranezza nel modo MVC genera i nomi dei campi. La vista parziale non tiene conto del fatto che il modello è una raccolta quando genera il nome del campo. Immagino se gli Articoli.viene creato a livello di vista anziché a livello di vista parziale, quindi potrebbe non esserci un buon modo per risolverlo. Grazie. –
kondotine: sembra un bug di asp.net mvc, qualcuno lo ha ancora segnalato? – Wout
Ok, mi sono riferito: http://aspnet.codeplex.com/workitem/7711, votare per questa correzione! – Wout