Ich versuche, eine Liste zu binden, die Teil eines größeren Ansichtsmodells ist, ohne auf einen benutzerdefinierten Modellbinder zurückzugreifen. Wenn ich eine Editorvorlage verwende, um die Liste der Eingaben zu erstellen, haben die generierten Namen nicht das richtige Format, damit der Standardordner funktioniert.ASP.NET MVC Model Binding IList in einem Editor Template
Anstelle von Items [3] .Id wie ich würde erwarten, dass es Items ist. [3] .Id. Wenn ich die Liste ohne eine Editor-Vorlage erstelle, funktioniert es wie erwartet.
Mache ich etwas offensichtlich falsch oder ist das nur eine Eigenart von Html.Hidden und 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>
<%
}%>
Ausgabe
<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>
bearbeiten (Aktion Methode)
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 } }
}
});
}
Edit # 2
Httppost Aktion
[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>
Es ist also wirklich eine Marotte in der Art und Weise MVC die Feldnamen erzeugt. Die Teilansicht berücksichtigt nicht, dass das Modell eine Sammlung ist, wenn der Feldname generiert wird. Ich denke, wenn die Items.wird auf der Ansichtsebene statt auf der Ebene der Teilansicht erstellt, und es ist möglicherweise kein guter Weg, sie zu beheben. Vielen Dank. –
kondotine: klingt wie ein asp.net mvc bug, hat jemand es noch gemeldet? – Wout
Ok, melde mich selbst: http://aspnet.codeplex.com/workitem/7711, bitte stimme für diesen Bugfix! – Wout