public ActionResult GetColorSizeQty(){var data = new AdminProductDetailModel();data.colorList = commonCore.getallTypeofList("color");data.sizeList = commonCore.getallTypeofList("size");返回部分视图(数据);}[HttpPost]公共 ActionResult AddDetail(AdminProductDetailModel 模型){....}
DefaultModelBinder 要求集合项的索引器从零开始并且是连续的,或者表单值包括 Index=someValue,其中索引器是 someValue(例如 <input name="[ABC].productTotalQuantity" ..><input name="Index" value="ABC">.这个有解释在 Phil Haack 的文章 Model Binding To A 中有详细介绍列表.使用索引方法通常更好,因为它还允许您从列表中删除项目(否则需要重命名所有现有控件以便索引器是连续的).
解决您的问题的两种可能方法.
选项 1
将 BeginItemCollection 帮助程序用于局部视图.此帮助程序将根据 GUID 为 Index 值呈现隐藏输入.在局部视图和渲染现有项目的循环中都需要它.你的部分看起来像
$('#addField').click(function() {var index = (new Date()).getTime();var clone = $('#NewItem').clone();//更新克隆的索引器和索引值clone.html($(clone).html().replace(/[#]/g, '[' + index + ']'));clone.html($(clone).html().replace(/"%"/g, '"' + index + '"'));$('#yourContainer').append(clone.html());}
I have added a button in my view. When this button is clicked partial view is added. In my form I can add as much partial view as I can. When Submitting this form data I am unable to send all the partial view data to controller.
I have made a different model having all the attributes and I have made a list of that model to my main model. Can anyone please give me some trick so that I can send all the partial view content to my controller?
Your problem is that the partial renders html based on a single AdminProductDetailModel object, yet you are trying to post back a collection. When you dynamically add a new object you continue to add duplicate controls that look like <input name="productTotalQuantity" ..> (this is also creating invalid html because of the duplicate id attributes) where as they need to be <input name="[0].productTotalQuantity" ..>, <input name="[1].productTotalQuantity" ..> etc. in order to bind to a collection on post back.
The DefaultModelBinder required that the indexer for collection items start at zero and be consecutive, or that the form values include a Index=someValue where the indexer is someValue (for example <input name="[ABC].productTotalQuantity" ..><input name="Index" value="ABC">. This is explained in detail in Phil Haack's article Model Binding To A List. Using the Index approach is generally better because it also allows you to delete items from the list (otherwise it would be necessary to rename all existing controls so the indexer is consecutive).
Two possible approaches to your issue.
Option 1
Use the BeginItemCollection helper for your partial view. This helper will render a hidden input for the Index value based on a GUID. You need this in both the partial view and the loop where you render existing items. Your partial would look something like
Manually create the html elements representing a new object with a 'fake' indexer, place them in a hidden container, then in the Add button event, clone the html, update the indexers and Index value and append the cloned elements to the DOM. To make sure the html is correct, create one default object in a for loop and inspect the html it generates. An example of this approach is shown in this answer
<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>
Note the use of a 'fake' indexer to prevent this one being bound on post back ('#' and '%' wont match up so they are ignored by the DefaultModelBinder)
$('#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());
}
The advantage of option 1 is that you are strongly typing the view to your model, but it means making a call to the server each time you add a new item. The advantage of option 2 is that its all done client side, but if you make any changes to you model (e.g. add a validation attribute to a property) then you also need to manually update the html, making maintenance a bit harder.
Finally, if you are using client side validation (jquery-validate-unobtrusive.js), then you need re-parse the validator each time you add new elements to the DOM as explained in this answer.