[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 987
  • Last Modified:

MVC SaveChanges Model with Nested List?

I have a model with a List and need to save changes. The VS 2012 debugger shows the Edit action model contains all indexed data. I'm used editor templates to achieve this.
The action method posted does not error and does not save the 'Limit' property changes. Help!

[Models]
    public class BudgetEdit
    {
        public List<BudgetList> BudgetList { get; set; }
    }

    public class BudgetList
    {
        public string Name { get; set; }
        public Nullable<int> ItemID { get; set; }
        public decimal Limit { get; set; }
        public System.DateTime Posted { get; set; }
    }


 [Action]
    public ActionResult Edit(Models.BudgetEdit model)
    {            
         var r = context.Budgets.Select(x => x.ItemID == model.BudgetList.FirstOrDefault().ItemID);

          if (r != null)
          {
              TryUpdateModel(r);
              context.SaveChanges();
          }
          return View((model);
     }
0
WorknHardr
Asked:
WorknHardr
  • 5
  • 4
1 Solution
 
Bob LearnedCommented:
What does the view look like?  Is this supposed to be a POST method, with [HttpPost] attribute?
0
 
WorknHardrAuthor Commented:
okay, here's the View and Editor Template complete code.

Note: I renamed the above posted model from 'BudgetEdit' to 'BudgetEditView ' because it's more intuitive.

I included a 'For' loop in the Action to step-through each List item, although I still don't have the mapping correct yet.

I've been exploring AutoMapper (unsuccessfully) like so:

[Action]
  public ActionResult Edit(BudgetEditView model)
  {
        for (int i = 0; i < model.BudgetList.Count; i++)
            {
                Budget b = context.Budgets.Find(model.BudgetList(i).ItemID);
                AutoMapper.Mapper.Map(model.BudgetList, b);
                context.SaveChanges();
            }
  }      

[View]
@model BudgetProjectUI.BudgetEditView

 @using (Html.BeginForm("Edit", "Budget", FormMethod.Post))
        {
            @Html.ValidationSummary(false)

            <fieldset>
                <legend>Month/Year </legend>
                <table>
                    <thead>
                        <tr>
                            <td><b>Category</b></td>
                            <td></td>
                            <td><b>Limit</b></td>
                        </tr>
                    </thead>
                    <tbody>

                        @Html.EditorFor(model => @Model.BudgetList)

                    </tbody>
                </table>
            </fieldset>  
                                               
            <input type="submit" value="Save Changes" />

[Editor Template]
@model BudgetProjectUI.BudgetList

<table>
    <tr>        
        <td>@Html.HiddenFor(model => model.BudgetID)</td>
        <td>@Html.HiddenFor(model => model.ItemID)</td>
        <td>@Html.HiddenFor(model => model.CategoryID)</td>
        <td style="width:150px">
            @Model.Name

        </td>
        <td></td>
        <td></td>
        <td>
            <div style="width:50px">
                @Html.EditorFor(model => model.Limit)

            </div>
        </td>
    </tr>
</table>
0
 
Bob LearnedCommented:
You have a submit button, but I don't see that the action method has an HttpPost attribute.

Here is some "light reading" that should explain the need for HttpPost:

When to use [HttpGet] vs. [HttpPost] in ASP.NET MVC
http://www.linkedin.com/groups/When-use-HttpGet-vs-HttpPost-43315.S.261572227
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
WorknHardrAuthor Commented:
Hmmm, interestingly enough the VS 2012 debugger shows the Edit action model contains all indexed data.
0
 
Bob LearnedCommented:
I overlooked this line, which does the same thing:

@using (Html.BeginForm("Edit", "Budget", FormMethod.Post))

If you are using Entity Framework, it is possible to determine what changes are detected.

public static void TestEntityState(BaseEntity entity)
{
   var state = _dataContext.ObjectStateManager.GetObjectStateEntry(entity);
   var propertyList = state.GetModifiedProperties();

   foreach (var property in propertyList)
   {
       Console.WriteLine("Property {0} changed from {1} to {2}", 
           property,
           state.CurrentValues[property],
          state.OriginalValues[property]);
   }
}

Open in new window

0
 
WorknHardrAuthor Commented:
Okay, here's my latest failed attempt to save a collection back to its model. I receive the following error on 'var' below.

Q. So it must be pure Lambda to not error?

 "Error: LINQ to Entities does not recognize the method 'BudgetProjectUI.BudgetList get_Item(Int32)' method, and this method cannot be translated into a store expression."


  public ActionResult Edit(BudgetEditView model)
  {
         for (int i = 0; i < model.BudgetList.Count; i++)
         {
                var changes = (from b in context.Budgets where b.BudgetID == model.BudgetList(i).BudgetID select b.Limit).First();

                changes = model.BudgetList(i).Limit;
                context.SaveChanges();
          }
   }
0
 
Bob LearnedCommented:
I showed you that code, so that you could double check the changes applied to Entity Framework.  That way, you could check to see if Limit was included in the changeset.
0
 
WorknHardrAuthor Commented:
Understood! I hope MVC 5 has a better way to do these things. Until then I'll use a reliable FormCollection.
0
 
WorknHardrAuthor Commented:
Thx for helping...
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now