How do partial views access the index of an array that is located in the calling method?
Trying to work out how MVC gets the index of an array within a partial view.
I have the following code to demonstrate.
public class HomeController : Controller {
public ActionResult Index() {
return View(new[] {
new Custome开发者_JAVA百科r() {
Orders = new [] {
new Order() { Name="Shoes" },
new Order() { Name="Socks" },
}
},
new Customer() {
Orders = new [] {
new Order() { Name="Pants" },
new Order() { Name="Pantaloonies" },
}
}
});
}
}
My Index.aspx view
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%: Html.EditorForModel("_Customer") %>
</asp:Content>
My _Customer.ascx
<% using(Html.BeginForm("Index", "Home", FormMethod.Post)) { %>
<% for (int i = 0; i < Model.Length; i++) { %>
<% for (int i2 = 0; i2 < Model[i].Orders.Count(); i2++) { %>
<%= Html.EditorFor(m => m[i].Orders[i2], "Orders")%>
<% } %>
<% } %>
<input type="submit" value="submit" />
<% } %>
My Order.ascx
<%= Html.LabelFor(m => m.Name) %>
<%= Html.EditorFor(m => m.Name) %>
The following HTML is rendered
<form action="/" method="post">
<label for="[0]_Orders[0]_Name">Name</label>
<input class="text-box single-line" name="[0].Orders[0].Name" type="text" value="Shoes" />
<label for="[0]_Orders[1]_Name">Name</label>
<input class="text-box single-line" name="[0].Orders[1].Name" type="text" value="Socks" />
<label for="[1]_Orders[0]_Name">Name</label>
<input class="text-box single-line" name="[1].Orders[0].Name" type="text" value="Pants" />
<label for="[1]_Orders[1]_Name">Name</label>
<input class="text-box single-line" name="[1].Orders[1].Name" type="text" value="Pantaloonies" /><input type="submit" value="submit" />
</form>
Where does Order.ascx get access to the index of the array from it's parent? I want to be able to set the index manually for one off ajax calls so I can fake the increment value.
It seems that the Html.EditorFor() methods use reflection to get the context from which they are being executed to get the index of the current loop.
The answer is to set the HtmlFieldPrefix in your TemplateInfo so that your partial views have access to it.
ViewData.TemplateInfo.HtmlFieldPrefix = "[0]_Orders[1]"; %>
Obviously you'd replace the numbers with the value of the current for loop or a counter variable.
精彩评论