问题
Quick question regarding updating a list of items in asp.net mvc.
Basically I have an edit action method that returns a collection of objects (incidentally, the table structure of which looks as follows 'testID, assetID, Result' - a link table).
I basically want this items to be displayed one after another in a form and to be able to edit them. The form should post back and the modelbinder do its magic. But, its not that easy.
I have scoured the net and it seems the majority of the information about this stuff seems to be a little out of date. I've come across this post, which has not been updated in a long time, and this one which seems to suggest that you shouldn't bind to a already existing list for updating, and that there are problems when working with EF or Linq to Sql (which I am).
Is there an easy way to achieve what I want? Has the state of list model binding changed in the release version?
UPDATE - A little closer...
Here's my Edit method:
public ActionResult EditSurveyResults(Guid id)
{
var results = surveyRepository.GetSurveyResults(id);
return PartialView("EditSurveyResults", results);
}
And my form:
<div id="editSurveyResults">
<h2>
EditSurveryResults</h2>
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm())
{%>
<fieldset>
<legend>Results</legend>
<% int i = 0; foreach (var result in Model)
{ %>
<input type="hidden" name='results[<%= i %>].TestID' value='<%= result.TestID %>' />
<input type="hidden" name='results[<%= i %>].AssetID' value='<%= result.AssetID %>' />
<p>
<%= result.Task.TaskName%>
</p>
<p>
<label for="Result">
Result:</label>
<input type="text" name='results[<%= i %>].Result' value='<%= result.Result %>' />
<%= Html.ValidationMessage("Result", "*")%>
</p>
<% i++; } %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
And my Edit POST method:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditSurveyResults(Guid id, IList<SurveyTestResult> results)
{
var oldValues = surveyRepository.GetSurveyResults(id);
if (ModelState.IsValid)
{
UpdateModel(oldValues);
surveyRepository.Save();
return Content("Done");
}
else
return PartialView("EditSurveyResults");
}
It's not complete of course, but it doesn't update anything in its current state. Am I missing a trick here? results is populated with the the updated entities so I'm not sure why its not updating...
UPDATE 2: So, Im starting to think that the model binder cant do stuff like this. So, I've resorted to doing things in a more hacky way. If anyone can spot a problem with this then please let me know. FYI - this form will be grabbed with AJAX so I dont return a view, rather a simple message. Here's the new code:
IList<SurveyTestResult> oldValues = surveyRepository.GetSurveyResults(id).ToList();
foreach (var result in SurveyTestResult)
{
//SurveyTestResult is the IList that comes down from the form.
SurveyTestResult thisone = oldValues.Single(p => p.AssetID == result.AssetID &&
p.TestID == result.TestID);
//update the old entity with the result from the new one
thisone.Result = result.Result;
}
And then I call Save on my repository.
Thanks in advance
回答1:
One thing i noticed is that your not rendering <input type="hidden" name='results.Index' value='<%= i %>' />
as phil Haacks article mentions is mandatory.
Switching to a different Modelbinder might do the trick too. I use the DataAnnotations model binder and with that i dont have to generate .Index
fields when binding to List
's.
来源:https://stackoverflow.com/questions/1565132/asp-net-mvc-updating-a-list-of-objects-on-one-form-model-binding-to-a-list