Cheung
Cheung

Reputation: 15552

ASP.NET MVC , proper way to persist dynamic selectList?

I am learning on MVC4+EF 5.0 project, i using VS2012 default template to create blank project and scaffolding the database to *.edmx model, and a edit view which use for edit a staff working on which company.

I experience a problem is maintenance the SelectList in edit view(Dropdown) when user fail input and return to it.

The DropDownList bind the ListItem from controller:

Edit.cshtml

@Html.DropDownListFor(model => model.CompanyID, (SelectList)ViewData["CompanySelectList"])

MemberController.cs

[HttpGet]
public ActionResult Edit(int SelectedCompanyID = 0, int StaffID = 0)
{
    IQueryable<company_benefit> companys = from c in db.company where c.ID.Equals(CompanyID) select c ;
    ViewData["CompanySelectList"] = new SelectList(companys, "ID", "Name", SelectedCompanyID);

    staff s = db.staff.Find(StaffID);
    if (s == null)
    {
        return HttpNotFound();
    }
    return View(s);
}


    [HttpPost]
    public ActionResult Edit(staff s)
    {
        if (ModelState.IsValid)
        {
            db.Entry(s).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index"); //Edit Success
        }

        return View(s); //Edit Fail
    }

If someone submit the form with invalid data resulting fail input, It will return the view. However, the SelectList is bind from ViewData, so the ViewData will gone when the page is loaded, and it is behavior of viewdata ,and i change to TempData is not help too.

So do i need build the SelectList again when Post to Edit Action?

I concern to use session to store that, but afriad to break to MVC design pattern.

My english is not good, sorry for confusion. Thanks you.

Upvotes: 0

Views: 669

Answers (1)

Farrukh Subhani
Farrukh Subhani

Reputation: 2038

A quick solution is In your http post method for edit again create your view data

[HttpPost]
public ActionResult Edit(staff s)
{
    if (ModelState.IsValid)
    {
        db.Entry(s).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index"); //Edit Success
    }
    IQueryable<company_benefit> companys = from c in db.company where c.ID.Equals(CompanyID) select c ;
    ViewData["CompanySelectList"] = new SelectList(companys, "ID", "Name", SelectedCompanyID);


    return View(s); //Edit Fail
}

What you are doing is basically saying that when you return from your edit view to the server then server should rebuild view data and call the same view so it can populate the list.

There is a better way where you can create a model which includes both your current model and a list<companys> companies = new list<companys>(); and then populate it again from database. Again the concept is same just using strongly typed model.

Upvotes: 1

Related Questions