views:

28

answers:

1

I'm kind of confused...

I have one action that takes an ID, loads up an object, and passes it to the View which is bound to the Model of that object's type.

After editing the data in the form supplied by the View, I POST back to another action that accepts an object of the same exact type as the Model.

However at this point I can't just call Repository.Save, I think I have a brand new object now, no longer associated with the one from the original database query that was sent to the View.

So how can I update the previously queried object and save the changes to the DB instead of getting a new object back from the View?

I even tried getting a new instance of the object from the DB and assigning the View returned object to it, and then Repo.Save(), still no such luck.

What am I doing wrong here?

CONTROLLER CODE:

[Authorize]
public ActionResult EditCompany(int id)
{
    //If user is not in Sys Admins table, don't let them proceed
    if (!userRepository.IsUserSystemAdmin(user.UserID))
    {
        return View("NotAuthorized");
    }

    Company editThisCompany = companyRepository.getCompanyByID(id);

    if (editThisCompany == null)
    {
        RedirectToAction("Companies", new { id = 1 });
    }

    if (TempData["Notify"] != null)
    {
        ViewData["Notify"] = TempData["Notify"];
    }

    return View(editThisCompany);
}

//
// POST: /System/EditCompany

[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditCompany(Company company)
{
    string errorResponse = "";

    if (!isCompanyValid(company, ref errorResponse))
    {
        TempData["Notify"] = errorResponse;
        return RedirectToAction("EditCompany", new { id = company.CompanyID });
    }
    else
    {
        Company updateCompany = companyRepository.getCompanyByID(company.CompanyID);
        updateCompany = company;
        companyRepository.Save();
        return RedirectToAction("EditCompany", new { id = company.CompanyID });
    }


    return RedirectToAction("Companies", new { id = 1 });
}
A: 

Try using the TryUpdateModel method. This way you can get the company from the repository before you databind to it.

[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditCompany(int id, FormCollection form)
{
    //Default to a new company
    var company = new Company();

    //If we have an id, we must be editing a company so get it from the repo
    if (id > 0)
        company = companyRepository.getCompanyByID(id);

    //Update the company with the values from post
    if (TryUpdateModel(company, form.ToValueProvider()))
    {
        string errorResponse = "";

        if (!isCompanyValid(company, ref errorResponse))
        {
            TempData["Notify"] = errorResponse;
            return RedirectToAction("EditCompany", new { id = company.CompanyID });
        }
        else
        {
            companyRepository.Save();
            return RedirectToAction("EditCompany", new { id = company.CompanyID });
        }
    }

    return RedirectToAction("Companies", new { id = 1 });
}

HTHs,
Charles

Ps. generally it's a bad idea to databind to your domain models... use presentation models instead and then you can get around this whole issue.

Charlino