Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net mvc update multiple records

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);
        }
like image 874
Mark Avatar asked Feb 20 '23 08:02

Mark


2 Answers

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.

like image 125
Shyju Avatar answered Mar 02 '23 23:03

Shyju


Suppose you have a model called Person.. and you want to edit a bunch of persons in a View and post them to an action.

public ViewResult Edit()
{
    return View(list of persons to edit);
}

public ViewResult Edit(List<Person> persons)
{
    // save to db?
}

Now to create a view that displays say multiple persons to edit.

Edit.cshtml

@model List<Person>

@for (int i = 0; i < Model.Count; i++) {
   <h4>Person Number: @i</h4>
   @:First Name: @Html.EditorFor(m => m[i].FirstName)
   @:Last Name: @Html.EditorFor(m => m[i].LastName)
}
like image 38
VJAI Avatar answered Mar 02 '23 23:03

VJAI