Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Sam 47 posts 153 karma points
    Dec 10, 2014 @ 15:19
    Sam
    0

    Umbraco 7 SurfaceController Persist ModelState/Model

    I was playing around with SurfaceControllers and noticed that when I turned off JavaScript in my browser that my form no longer worked as expected. The form would post with the fields I entered, would go through the validation logic, ModelState would be set, RedirectToCurrentUmbracoPage() is called, and then I am presented with a blank form and no error messages.

    The only thing I could think of was that during the umbraco.tv SurfaceController series, Tim used TempData to send a success flag back to the View. This seems to indicate that the page is redirecting and that the ModelState would not be available for the current request.

    Using that theory I stored the ModelState and Model in TempData and loaded it in the initial view like so:

    public ActionResult Index()
    {
        ContactFormModel model = new ContactFormModel();
        if (TempData["Model"] != null)
            model = TempData["Model"] as ContactFormModel;
        if (TempData["ModelState"] != null && !ModelState.Equals(TempData["ModelState"]))
            ModelState.Merge((ModelStateDictionary)TempData["ModelState"]);
        return PartialView("ContactForm", model);
    }

    [HttpPost]
    public ActionResult Submit(ContactFormModel model)
    {
        if (ModelState.IsValid)
        {
            // Send email
            TempData["success"] = true;
        }
        else
        {
            TempData["ModelState"] = ModelState;
            TempData["Model"] = model;
        }
        return RedirectToCurrentUmbracoPage();
    }

    Is this currently the best way to handle this? Or is there a helper hidden somewhere that I can use to persist the model state? If not, might I recommend creating another RedirectToCurrentUmbracoPage variant that takes the ModelState as a parameter, and create another helper to load it into the initial view?

  • Tim 1193 posts 2675 karma points MVP 3x c-trib
    Dec 10, 2014 @ 15:35
    Tim
    100

    Rather than RedirectToCurrentUmbracoPage() (which is indeed a full redirect, which will nuke your ModelState), if you want to keep model state etc, use CurrentUmbracoPage() instead, which doesn't redirect, and should maintain your model state :)

  • Sam 47 posts 153 karma points
    Dec 10, 2014 @ 15:46
    Sam
    0

    Awesome, just verified that this does maintain ModelState. However, it doesn't appear that I have the ability to use ViewBag and still have to use TempData if I want to pass other information not included in the model. Is that correct?

  • Tim 1193 posts 2675 karma points MVP 3x c-trib
    Dec 10, 2014 @ 17:27
    Tim
    0

    Hi Sam,

    I'm not sure on that one, as I've not tried to use ViewBag in this kind of situation, I've usually used TempData. Someone else might be able to answer that one, sorry!

  • Sam 47 posts 153 karma points
    Dec 24, 2014 @ 05:00
    Sam
    0

    Tim, I did some testing and it looks like ViewBag does not work. I have to use TempData. The only time I see this being an issue is if you are on a web farm where your response may not be served by the same server, or when ASP.net Sessions are disabled. TempData uses Session by default to store the values. The only workaround I can think of at this time is to create a new TempDataProvider that utilizes cookies instead of session state.

Please Sign in or register to post replies

Write your reply to:

Draft