0

I have poked around but not found out what the ViewModel, or TempData or how my objects are being persisted for my form.

I display a custom view model in an asp.net MVC view, I edit a list of objects in that view and display them all inside a dynamic grid inside an html form, then submit the changes. When I get back to the controller I check existing objects vs the forms submitted object list and update the objects.

When I redisplay the form, objects that were deleted still show up and have values in the textbox inside the html elements, so it is asp popluating the fileds and not a browser cache. I have a checkbox that displays next to the row if it is an existing object already and those checkboxes are submitted to the controller as an array of values (the id of the object to remove).

So I delete the object, pull clean ones out of the database and set the list in the viewmodel with the newly retrieved data. However, the form shows the old object still, but there is no delete checkbox next to them so they were not retrieved from the database.

How do I fix that? I tried tweaking the methods output cache (not a browser issue as the DB ID key does not exists anymore ... no delete checkbox). I tried making a new view model an explicitly setting variables before sending to the view...no go. My solution for now was to redirect to the get method after I edit all of the objects (simpleObject in the example) and start completely over.

A simplified example is as follows:

public class CustomViewModel {
List<SimpleObject> objects {get;set;}
}
public class SimpleObect {
public int iA {get;set;}
      public int AddonHistID {get;set;}
}

Controller:

    [HTTPGet] // get method and displays 2 objects by default
   public ActionResult whatever( string something){
CustomViewModel  form = new CustomViewModel ();
form.objects = new List<SimpleObject>();
form.objects.Add( new SimpleObect());
form.objects.Add( new SimpleObect());
return View( form)
   }

[HttpPost]
public ActionResult whatever( string something, CustomViewModel form){

// adjust objects to show current objects aftering saving changes (reload and rebind to ModelView)
form.objects = getObjectsAfterChange( something); // just gets objects from db after all changes are made in this controller action
return View( form);
}

View:

<% using( Html.BeginForm()) { %>
<table width="800" id="SearchAddonsResults">
 foreach( SimpleObject addonHist in Model.objects )
 {
 ++iOdd;
 string cssClass = (iOdd % 2 == 0 ? "rowOdd" : "rowEven");
 %>
        <tr class="<%= cssClass %>">
            <td>
    <%if (addonHist.AddonID > 0)
              { %>
            <input type="checkbox" name="RemoveAddon" id="RemoveAddon" value="<%= addonHist.AddonID.ToString() %>" />
            <% } %>
<%= addonHist.AddonHistID.ToString() %>
        </td>
            <td><%= addonHist.iA.ToString() %></td>
    </tr>

<% } %>
</table>
<% }; //endform %>
tereško
  • 58,060
  • 25
  • 98
  • 150
Philmee95
  • 25
  • 2
  • 8
  • I realize that your example has been simplified, but it looks like your loop will end up generating invalid HTML. You have "RemoveAddon" hard-coded as the name and id for all of the input tags that are generated. What happens if you add some sort of index or other value to ensure that at least the id of the input tag is unique for each iteration of the loop? – TLS Nov 03 '11 at 01:14

2 Answers2

1

I think this might help you get the results you expect.

Phil Haack's Blog: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Which is linked to from:

How to model bind to a List<ViewModel>?

Complex model binding to a list

How ASP.NET MVC: How can I bind a property of type List<T>?

Community
  • 1
  • 1
TLS
  • 3,090
  • 2
  • 25
  • 33
0

So I delete the object, pull clean ones out of the database and set the list in the viewmodel with the newly retrieved data. However, the form shows the old object still,

This makes no sense. Are you absolutely sure that this line

form.objects = getObjectsAfterChange( something);

in your HttpPost method is retrieving the right information?

I would start by inspecting the value that getObjectsAfterChange( something) is returning . I suspect it's returning more than you think and that's where the problem is (rather than on the render of the view.)

Hector Correa
  • 26,290
  • 8
  • 57
  • 73