views:

77

answers:

2

I have a form which a user can fill in x times with the data they want too. The form is posted to the following Action.

        [HttpPost]
        public ActionResult Manage(ProductOptionModel DataToAdd)
        {
            if (!ModelState.IsValid)
            {
                return View(DataToAdd);
            }

            var ProdServ = new ProductService();

            if (DataToAdd.ID != 0)
            {
                //Edit Mode.
                DataToAdd = ProdServ.EditProductOption(DataToAdd);
                ViewData["Message"] = "Option Changes Made";

            }else
            {
                //Add
                DataToAdd = ProdServ.AddProductOption(DataToAdd);
                ViewData["Message"] = "New Option Added";
            }

            var RetModel = new ProductOptionModel() {ProductID = DataToAdd.ProductID};
            return View(RetModel);
        }

So at the bottom I blank the model (Leaving just the required field) and then return to the view. However the view holds the data from the previously submitted form.

Any ideas why? I have debugged the code and checked that the RetModel variable is empty.

A: 

This is because the build in input helpers will look at the posted data first and use those values if they exist. Then it will look at the model.

Mattias Jakobsson
+1  A: 

Html helpers work this way when a view is returned on HTTP POSTs. They prefer post data over model values.

Use Post/Redirect/Get

That's why I suggest you use the Post/Redirect/Get pattern that's very well supported in Asp.net MVC. Your controller actions should redirect to some GET action after POST has successfully completed as it is in your case.

public ActionResult Process()
{
    return View(new Data { Id = -1 });
}

[HttpPost]
public ActionResult Process(Data data)
{
    if (!this.ModelState.IsValid)
    {
        return View(data);
    }
    new MyService().ProcessData(data);
    return RedirectToAction("Process");
}

And if you display all previously entered data you can provide those in in the GET action or transfer them from POST to GET action using TempData dictionary.

Robert Koritnik
@Robert Koritnik This approach will work and looks good but, I have a message field (Currently ViewData) that I my need to pass to the user (Telling success,error etc etc) How can i do that using this method since ViewData is lost when RedirectToAction is called.
Pino
Use TempData to send your message. Alternatively you can clear out the model data, using ModelState.Clear(), before you return your View and leave your code as is. But I also prefer the Post/Redirect/Get for a long term solution.
Jab
Validation model state errors are not a problem since they don't redirect as per my code. Success is a different story. I suggest you use `TempData` dictionary as @Jab suggested. `TempData` is there exactly for the purpose of the Post/Redirect/Get pattern. Read about it on the web.
Robert Koritnik