问题
I need to make a view which will support bulk inserting of objects. I am using the repository pattern with Entity Framework 4.
Since there will be multiple individual models in the View, how do I handle binding the view's model to what get's sent to the Repository?
How do I retreive the input values from the form into the controller?
I have managed to do the view but I am unable to retrieve the data from controller. I used the folowing statement but after the post it heppens to be nul
public ActionResult AddPaymentForRoot_post(PaymentViewModelObject payments) {
return null;
}
回答1:
I haven't used EF yet, but I have a similar requirement on our site. I accomplished it by specifying the View as inheriting System.Web.Mvc.ViewPage<IEnumerable<MyModelObject>>
then use a for loop to build multiple input sections, utilizing the naming conventions required to allow the model binder to build the enumerable.
I prefer to create a view model with a property that is an enumerable (see update 2 below). In this example we could say it would be the MyViewModel
object with an IEnumerable<MyModelObject>
property called MyModelObjects
. In this case, the view would play out as follows...
Specifically, make sure to include for each input section a hidden field named MyModelObjects.Index
, then have your property inputs named MyModelObjects[0].MyProperty
, where the value of the Index
hidden field corresponds to the array index in the property names.
What you would end up with would look like this, for example:
<div>
<input type="hidden" name="MyModelObjects.Index" value="0" />
Name: <input type="text" name="MyModelObjects[0].Name" /><br />
Value: <input type="text" name="MyModelObjects[0].Value" />
</div>
<div>
<input type="hidden" name="MyModelObjects.Index" value="1" />
Name: <input type="text" name="MyModelObjects[1].Name" /><br />
Value: <input type="text" name="MyModelObjects[1].Value" />
</div>
<div><a href="#" id="addItem">Add another item</a></div>
In some cases I also have javascript (triggered by the anchor link in the markup above) that will clone a template input section, modify the names to populate the index value, and add it to the DOM. In this way users can dynamically add records to the view.
Depending on how you are handling your models, you may also pass in a ViewModel that has a property that is IEnumerable. The typing for the view would change, but fundamentally the design of the view wouldn't.
UPDATE Using the example above, here's a quick snippet of the jQuery code I use to add items. I'm assuming this is an insert, but note the comments if you wanted to support this type of interface for editing as well.
First, I set up a template. While this could be built totally in jQuery, I just find it easier to do the markup and manipulate the names.
<div id="templateDiv" style="display: none;">
<input type="hidden" name="MyModelObjects.Index" value="0T" />
Name: <input type="text" name="MyModelObjects[0T].Name" /><br />
Value: <input type="text" name="MyModelObjects[0T].Value" />
</div>
You can also specify IDs in there...probably a good practice, but in the interest of brevity I'll leave it out for the example.
With that, you can set up the jQuery function as follows:
var currentIndex = 1 // if you were using this for editing, this would be dynamically set to the number of items you have
var doAddItem =
function() {
currentIndex++;
var newItem = $("#templateDiv").clone();
newItem.attr("id", "item" + currentIndex); // reset the ID here
newItem.find("input[name=MyModelObjects.Index]").val(currentIndex);
newItem.find("input[name$=.Name]").attr("name", "MyModelObjects[" + currentIndex + "].Name");
newItem.find("input[name$=.Value]").attr("name", "MyModelObjects[" + currentIndex + "].Value");
newItem.insertBefore($(this).closest("div")); // insert it before the div containing the add link...adjust appropriate to your layout
return false;
}
$(document).ready(function() {
$("#addItem").click(doAddItem);
// In a real-world app you'd probably want to have a delete option, too
});
UPDATE 2
There's a bit of an error up there - if your view is typed to an IEnumerable<object>
then your field names will end up just being Index
and [0].Name
/ [0].Value
. In my actual app I use a view model that has a property that is itself an enumerable, so I actually type my pages as <MyViewModelObject>
. In the example above, that view model object would have a property called MyModelObject
, which would be an enumerable (and more realistically called MyModelObjects
plural).
来源:https://stackoverflow.com/questions/4958739/how-do-i-save-multiple-models-edited-in-form-in-asp-net-mvc