Asp.net mvc 4 是否将名为多次数据的同一部分视图提交给控制器?

Asp.net mvc 4 是否将名为多次数据的同一部分视图提交给控制器?,asp.net-mvc-4,Asp.net Mvc 4,我在视图中添加了一个按钮。单击此按钮时,将添加部分视图。在我的表格中,我可以添加尽可能多的局部视图。提交此表单数据时,我无法将所有部分视图数据发送到控制器。 我制作了一个具有所有属性的不同模型,并将该模型的列表添加到我的主模型中。谁能给我一些技巧,让我可以发送所有的部分视图内容到我的控制器 在我看来 <div id="CSQGroup"> </div> <div> <input type="button" value="Add Field" i

我在视图中添加了一个按钮。单击此按钮时,将添加部分视图。在我的表格中,我可以添加尽可能多的局部视图。提交此表单数据时,我无法将所有部分视图数据发送到控制器。 我制作了一个具有所有属性的不同模型,并将该模型的列表添加到我的主模型中。谁能给我一些技巧,让我可以发送所有的部分视图内容到我的控制器

在我看来

<div id="CSQGroup">   
</div>
<div>
  <input type="button" value="Add Field" id="addField" onclick="addFieldss()" />
</div>

function addFieldss()
{    
  $.ajax({
    url: '@Url.Content("~/AdminProduct/GetColorSizeQty")',
    type: 'GET',
    success:function(result) {
      var newDiv = $(document.createElement("div")).attr("id", 'CSQ' + myCounter);  
      newDiv.html(result);
      newDiv.appendTo("#CSQGroup");
      myCounter++;
    },
    error: function(result) {
      alert("Failure");
    }
  });
}
在我看来

@model IKLE.Model.ProductModel.AdminProductDetailModel
<div class="editor-field">
  @Html.LabelFor(model => model.fkConfigChoiceCategorySizeId)
  @Html.DropDownListFor(model => model.fkConfigChoiceCategorySizeId, Model.sizeList, "--Select Size--")
  @Html.ValidationMessageFor(model => model.fkConfigChoiceCategorySizeId)
</div>
<div class="editor-field">
  @Html.LabelFor(model => model.fkConfigChoiceCategoryColorId)
  @Html.DropDownListFor(model => model.fkConfigChoiceCategoryColorId, Model.colorList, "--Select Color--")
  @Html.ValidationMessageFor(model => model.fkConfigChoiceCategoryColorId)
</div>   
<div class="editor-field">
  @Html.LabelFor(model => model.productTotalQuantity)
  @Html.TextBoxFor(model => model.productTotalQuantity)
  @Html.ValidationMessageFor(model => model.productTotalQuantity)
</div>

您的问题是,该部分基于单个AdminProductDetailModel对象呈现html,但您正在尝试发回一个集合。当您动态添加新对象时,您会继续添加重复控件,这些控件看起来也是在创建无效的html,因为重复的id属性需要在何处等,以便绑定到回发时的集合

DefaultModelBinder要求集合项的索引器从零开始并连续,或者表单值包括Index=someValue,其中索引器是someValue,例如。Phil Haack的文章对此进行了详细解释。使用索引方法通常更好,因为它还允许您从列表中删除项,否则需要重命名所有现有控件,以便索引器是连续的

两种可能的解决方法

选择1

使用局部视图的辅助对象。此帮助程序将基于GUID呈现索引值的隐藏输入。在局部视图和渲染现有项的循环中都需要此选项。你的头发看起来像

@model IKLE.Model.ProductModel.AdminProductDetailModel
@using(Html.BeginCollectionItem()) 
{
  <div class="editor-field">
    @Html.LabelFor(model => model.fkConfigChoiceCategorySizeId)
    @Html.DropDownListFor(model => model.fkConfigChoiceCategorySizeId, Model.sizeList, "--Select Size--")
    @Html.ValidationMessageFor(model => model.fkConfigChoiceCategorySizeId)
  </div>
  ....
}
请注意,使用“假”索引器可防止此索引器绑定到回发上,“%”将不匹配,因此它们将被DefaultModelBinder忽略

选项1的优点是,您可以在模型中强力键入视图,但这意味着每次添加新项时都要调用服务器。选项2的优点是它的客户端都完成了,但是如果您对模型进行了任何更改(例如,向属性添加验证属性),那么您还需要手动更新html,从而使维护变得更加困难

最后,如果使用客户端验证jquery-validate-unobtrusive.js,那么每次向DOM添加新元素时都需要重新解析验证器,如中所述

当然,您需要更改POST方法以接受集合

[HttpPost]
public ActionResult AddDetail(IEnumerable<AdminProductDetailModel> model)
{
  ....
}

请检查代码,如果需要查看更多内容,请让我知道表单的POST方法是什么?您提到了一个集合,但生成的部分视图不会发回集合。name属性不包含用于绑定到集合的索引器,请使用Html.begformadddetail、AdminProduct、FormMethod.post、new{@enctype=multipart/form data}{..form data}你是这个意思吗?不,我是说AddDetail方法的签名是什么?确切地说,我的部分观点必须在收集后发布,但它没有。你能给我一些技巧让我的部分视图发布收集谢谢你的帮助,但我已经通过你提到的技术解决了这个问题。啊,谢谢。我还没有真正达到我需要这个的程度,但当我需要它的时候,它肯定会派上用场;其他任何人来到这里,我强烈推荐BeginItemCollection助手。这感觉像是作弊。注意,还有一个ASP.NET内核包。对我来说效果很好。我不确定这是否是BeginCollectionItem中的更改,因为这是最初发布的,但这里没有提到,所以我会提出:BeginCollectionItem要求一个名为collectionName的字符串参数。这必须与您尝试链接到的集合的名称相匹配。例如,我的ParentViewModel有一个名为ChildViewModels的列表,因此在我的子部分视图中,我将有@usingHtml.BeginCollectionItemChildViewModels。
<div id="newItem" style="display:none">

  <div class="editor-field">
    <label for="_#__productTotalQuantity">Quantity</label>
    <input type="text" id="_#__productTotalQuantity" name="[#].productTotalQuantity" value />
    ....
  </div>
  // more properties of your model
</div>
$('#addField').click(function() {
  var index = (new Date()).getTime(); 
  var clone = $('#NewItem').clone();
  // Update the indexer and Index value of the clone
  clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']'));
  clone.html($(clone).html().replace(/"%"/g, '"' + index  + '"'));
  $('#yourContainer').append(clone.html());
}
$('form').data('validator', null);
$.validator.unobtrusive.parse($('form'));
[HttpPost]
public ActionResult AddDetail(IEnumerable<AdminProductDetailModel> model)
{
  ....
}