3
votes

I'm trying to figure out how to pass a model across views

Here is what I'm doing, I have a Register, RegisterConfirm, RegisterComplete views.

User starts at Register, fills info, clicks continue and posts to RegisterConfirm where they click checkbox to agree to privacy policy then post to RegisterComplete which creates the user based on the model in the first Register view.

Code:


        [GET("Account/Register")]
        public ActionResult Register()
        {
            return View();
        }

        [POST("Account/Register/Confirm")]
        public ActionResult RegisterConfirm(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                return View(model);
            }
            else { return View("Register", model); }
        }

        [POST("Account/Register/Complete")]
        public ActionResult RegisterComplete(RegisterModel model, bool agree)
        {
            if (agree) { 
                // Create User
            }
            return View("Register", model);
        }


View Form


Register:
    @using (Html.BeginForm("RegisterConfirm", "Account", FormMethod.Post, new { @id = "create" }))
    {

Register Confirm:
    @using (Html.BeginForm("RegisterComplete", "Account", FormMethod.Post, new { @id = "create" }))
    {


Problem is, when I'm getting to RegisterComplete, model values are empty... any ideas or is this not possible? Or should this work and I need to double check my registercomplete?

2

2 Answers

4
votes

Is your RegisterConfirm view using display-only elements to show the registration information? If so, MVC won't be able to bind the data to populate the model.

You need to render the model as Input elements, even if they're hidden, so that the model binder can populate RegisterModel (you can render the properties as both hidden elements for 'data retention' and output elements for display).

If you are using Input elements, check that the names of those elements match the property names of RegisterModel, otherwise, again, the model binder won't be able to populate RegisterModel.

If you can't, for whatever reason, put the data in Input elements in your RegisterConfirm view, you'll need to store the data somewhere server-side, either in Session State (or TempData, which uses Session State anyway) or in a database of some description.

The advantage with storing the model server-side is that you can be sure that the data hasn't been tampered with between sending it to the client and receiving it back.

4
votes

You can use TempData and store your model inside it and receive your model back from it

[POST("Account/Register/Confirm")]
            public ActionResult RegisterConfirm(RegisterModel model)
            {
                if (ModelState.IsValid)
                {
                    //store data for any other request
                    TempData["newUser"]=model;

                    return View();
                }
                else { return View("Register", model); }
            }

        [POST("Account/Register/Complete")]
        public ActionResult RegisterComplete(RegisterModel model, bool agree)
        {
            //retrieve data back irrespective of use choice 
            //to clear memory

            RegisterModel newUser= TempData["newUser"];

            if (agree) { 
                // Create User
                //use newUser
            }
            return View("Register", model);
        }