form 利用BeginCollectionItem提交集合List<T>数据 以及提交的集合中含有集合的数据类型 如List<List<T>> 数据的解决方案
例子:
public class IssArgs { public List<IssTabArgs> Tabs { get; set; } } public class IssTabArgs { public int Num { get; set; } public string Tab { get; set; } public List<IssArg> Args { get; set; } } public class IssArg { public int Num { get; set; } public string Name { get; set; } public string Value { get; set; } }
现在需要上传这样的数据
@using (Html.BeginForm("SaveGpIss", "Issue")) { @foreach (var item in Model.TabArgs.Tabs) { @Html.Partial("_ArgsTabPar",item) } }
@model Web.Models.Vm.Issue.IssTabArgs <tbody> @using (Html.BeginCollectionItem("TabArgs.Tabs")) { @Html.HiddenFor(m => m.Num, new { @class = "arg_tab_num" }) <tr class="un"> <td colspan="2" class="w">@Html.EditorFor(m=>m.Tab, new { HtmlAttributes = new { PlaceHolder = "表名称" } })</td> </tr> foreach (var item in Model.Args) { @Html.Partial("_ArgPar",item) } } </tbody>
下面是第级集合的重点
@model Web.Models.Vm.Issue.IssArg @{ var colId = ViewData.TemplateInfo.HtmlFieldPrefix; } <tr> @using (Html.BeginCollectionItem(colId + ".Args")) { @Html.HiddenFor(m=>m.Num,new {@class="arg_num"}) <td class="n">@Html.EditorFor(m => m.Name, new { HtmlAttributes = new { PlaceHolder = "参数名称" } })</td> <td class="i">@Html.EditorFor(m => m.Value, new { HtmlAttributes = new { PlaceHolder = "参数值" } })</td> } </tr>
ViewData.TemplateInfo.HtmlFieldPrefix;
BeginCollectionItem 反编译代码,将 Guid.NewGuid().ToString() 值储存 ViewData.TemplateInfo.HtmlFieldPrefix;
using System; using System.Collections.Generic; using System.IO; using System.Web; using System.Web.Mvc; namespace HtmlHelpers.BeginCollectionItem { public static class HtmlPrefixScopeExtensions { private const string IdsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_"; public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName) { return html.BeginCollectionItem(collectionName, html.ViewContext.Writer); } public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName, TextWriter writer) { Queue<string> idsToReuse = HtmlPrefixScopeExtensions.GetIdsToReuse(html.ViewContext.get_HttpContext(), collectionName); string str = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString(); writer.WriteLine("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", (object) collectionName, (object) html.Encode(str)); return html.BeginHtmlFieldPrefixScope(string.Format("{0}[{1}]", (object) collectionName, (object) str)); } public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix) { return (IDisposable) new HtmlPrefixScopeExtensions.HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix); } private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName) { string str1 = "__htmlPrefixScopeExtensions_IdsToReuse_" + collectionName; Queue<string> stringQueue = (Queue<string>) httpContext.Items[(object) str1]; if (stringQueue == null) { httpContext.Items[(object) str1] = (object) (stringQueue = new Queue<string>()); string str2 = httpContext.Request[collectionName + ".index"]; if (!string.IsNullOrEmpty(str2)) { string str3 = str2; char[] chArray = new char[1]{ ',' }; foreach (string str4 in str3.Split(chArray)) stringQueue.Enqueue(str4); } } return stringQueue; } internal class HtmlFieldPrefixScope : IDisposable { internal readonly TemplateInfo TemplateInfo; internal readonly string PreviousHtmlFieldPrefix; public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix) { this.TemplateInfo = templateInfo; this.PreviousHtmlFieldPrefix = this.TemplateInfo.HtmlFieldPrefix; this.TemplateInfo.HtmlFieldPrefix = htmlFieldPrefix; } public void Dispose() { this.TemplateInfo.HtmlFieldPrefix = this.PreviousHtmlFieldPrefix; } } } }
还有一种解决方式就是通过脚本的方式改变input name 的内容,这里不多说了