asp.net mvc update multiple records

asp.net, asp.net-mvc

Solution

Use an Editor template

Assuming your ViewModel/Model looks like this

public class UserViewModel 
{
  public int UserId { set;get;}
  public string Name { set;get;}   
  public IEnumerable<Address> Addresses { set;get;}

  public UserViewModel()
  {
     if(this.Addresses==null)
         this.Addresses=new List<Address>();
  }
}
public class Address
{
  public int AddressID { set;get;}
  public string AddressLine1 { set;get;}
}

Now create an editor template called `addresses.cshtml` with below content.

@model YourNameSpace.Address
@Html.TextBoxFor(x => x.AddressLine1)

In your main view, you can call this like

@model UserViewModel 
@using (Html.BeginForm())
{
  //other elements
 @Html.EditorFor(m=>m.Addresses)
 <input type="submit" value="Save" />
}

Now you will get the data in your HttpPost Ation method

[HttpPost]
public ActionResult Save(UserViewModel model)
{  
   foreach (Address address in model.Addresses)
   {
      //now check for address.AddressLine here
   } 
}

EDIT : Based on the user's comment and updation on the question.

(Request to the OP : Next time when you post a question, include all the relevant details to the question in the first time itself.)

Create a ViewModel to wrap your List of Objective class.

public class ObjectivesEdit
{
    public IEnumerable<Objective> Objectives { set; get; }
    public ObjectivesEdit()
    {
        if (Objectives == null)
            Objectives = new List<Objective>();
    }
}

And in your GET Action method send this Wrapper View model to the View with values filled

  public ActionResult Edit()
  {
     ObjectivesEdit objEdit = new ObjectivesEdit();
     List<Objective> objList = new List<Objective>();
       // you can replace this manual filling with data from database
     objList.Add(new Objective { ID = 1, score = 65 });
     objList.Add(new Objective { ID = 2, score = 43 });
     objList.Add(new Objective { ID = 3, score = 78 });
     objEdit.Objectives = objList;
     return View(objEdit);
  }

Your Editor template should look like this. It should be named `objective.cshtml`

@model EditorTemplateDemo.Models.Objective           
<p>
Score for @Model.ID is  @Html.TextBoxFor(x => x.score)
@Html.HiddenFor(x => x.ID)
</p>

And your main View

@model EditorTemplateDemo.Models.ObjectivesEdit
@using (Html.BeginForm())
{
  @Html.EditorFor(x=>x.Objectives)
  <input type="submit" value="Save" />    
}

And finally your HTTPPOST action method will look like this

    [HttpPost]
    public ActionResult Edit(ObjectivesEdit model)
    {
        if (model.Objectives != null)
        {
            // Put a break point here and you will see the posted data
            foreach (var item in model.Objectives)
            {
                 context.Entry(item).State = EntityState.Modified;
            }
            //Save and redirect  
            context.SaveChanges();
            return RedirectToAction("Index");     
        }
        return View(model);
    }

This should work. Tested.

To avoid further questions, I am sharing a working sample of the above code here. Please use visual studio breakpoints int he code to see what value is being posted.

Problem

is it possible to have a view for editing multiple records, in the same way that the index.cshtml view loops through records to display them (as below)? ``` @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.tvid) </td> ``` So for each row above, it would relate to a different row in the database. Does anyone know of any examples showing how this may be achieved? Thanks for any pointers, Mark UPDATE Model: ``` using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MvcObjectives.Models { public class objectives { public int ID { get; set; } public int tvid { get; set; } public string tlnt { get; set; } public DateTime month { get; set; } public string objective { get; set; } public int score { get; set; } public int possscore { get; set; } public string comments { get; set; } } ``` } Controller: ``` [HttpPost] public ActionResult Edit(objectives objectives) { if (ModelState.IsValid) { db.Entry(objectives).State = EntityState.Modified; foreach (objective Objective in objectives.objective) { } db.SaveChanges(); return RedirectToAction("Index"); } return View(objectives); } ``` I'm stick with the controller, if anyone can offer any assistance? Thanks again, Mark 2nd Update The GET Controller to send the records to the view is: ``` // GET: /Objective/Edit/ public ActionResult Edit() { return View(db.objectives.ToList()); } ``` The POST controller (where the values are posted back from the view) is: ``` // POST: /Objective/Edit/ [HttpPost] public ActionResult Edit(List<objectives> objectives) { if (ModelState.IsValid) { // the next part is where I am stuck - how to loop through the returned objectives, and update the records in the database db.Entry(objectives).State = EntityState.Modified; foreach (objectives obj in objectives) { var tempObj = (from objv in db.objectives where objv.ID==obj.ID select objv).First(); } // to do - how to save the updates sent back???? return RedirectToAction("Index"); } return View(objectives); } ```

Original source