I have an application where I need to input data and on submit the data gets saved in database. When I checked in database the input is getting saved successfully but I am getting an exception when the page reloads after httppost. I am getting exception at :

  @Html.DropDownList("LineID", new SelectList(Model.dropConfig, "LineID", "LineID"), "-- Select LineID --", new { required = true, @class = "form-control" })

Controller code to get the dropdownlist values, binding with Db:

   [ActionName("DetailsForm")]
        [HttpGet]
        public ActionResult DetailsForm()
        {
            try
            {
                var model = new DetailsViewModel() { dropConfig = floorService.DropDownList().ToList() };
                return View("DetailsForm", model);

            }
            catch (Exception ex)
            {
                return View("_error");
            }
        }

Controller code to http post:

 [ActionName("DetailsForm")]
        [HttpPost]

        public ActionResult DetailsForm(DetailsViewModel model, FormCollection form)
        {

            DetailsConfiguration detailsConfig = new DetailsConfiguration();

            detailsConfig.LineID = Convert.ToString(form["LineID"]);
            //Similary for other fields
            floorService.SaveDetails(detailsConfig);

            ModelState.Clear();
            ViewBag.message = "Success";

            return View("DetailsForm",model);

        }

Snapshot of exception: enter image description here

0
shrey Pav 15 November 2017, 05:25

1 menjawab

Jawaban Terbaik

Because your view code is using Model.dropConfig to build the SelectList for your dropdown, and you are not setting the dropConfig property value before returning to the view.

Remember, Http is stateless. So even though you set the dropConfig property value in the GET action, It won't be available inside your HttpPost action. When you submit your form, it is a totally new request to the server.

You can fix it by loading dropConfig property again.

model.dropConfig = floorService.DropDownList().ToList();
return View(model);

But ideally you should be following the P-R-G pattern.

P-R-G stands for Post-Redirect-Get. So when you submit your form to an http post action method, you should return a redirect response and the browser will make a new GET call to that action method.

Anda dapat menggunakan metode RedirectToAction untuk mengembalikan respons pengalihan.

floorService.SaveDetails(detailsConfig);
return RedirectToAction("DetailsForm");

This will send a 302 response back to the browser with the location header set to the url to the DetailsForm action method and the browser will make a new GET request to that.

ViewBag won't work when with redirect response. So you might consider using TempData. TempData can be used to transfer between two requests.

TempData["message"] = "Success";
return RedirectToAction("DetailsForm");

Now you can read TempData["message"] in the DetailsForm action method or the view rendered by that.

For example, you can read it in the view (rendered by DetailsForm GET action method) like this

@if (TempData["message"]!=null)
{ 
 <div class="alert alert-success" id="alert">
      <button type="button" class="close" data-dismiss="alert">x</button> 
    <strong>Success! </strong>@TempData["message"]
  </div> 
}
1
Shyju 15 November 2017, 02:56