模型数据在控制器之间消失

时间:2014-05-17 22:26:08

标签: c# asp.net-mvc

所以我有一个模型,里面有两个模型,这样我就可以在同一个视图,一个登录视图和一个注册视图上渲染到不同的视图。

这是我的模特:

public class SignUpLoginModel
{
    public LoginModel loginmodel { get; set; }
    public RegisterModel registermodel { get; set; }
}

当我尝试使用此控制器方法注册新用户时:

  public ActionResult Register(SignUpLoginModel model)
    {
        if (ModelState.IsValid)
        {
            // Attempt to register the user
            try
            {
                WebSecurity.CreateUserAndAccount(model.registermodel.UserName,
                    model.registermodel.Password,
                    new
                    {
                        FirstName = model.registermodel.Firstname,
                        LastName = model.registermodel.Lastname,
                        Country = model.registermodel.Country,
                        City = model.registermodel.City,
                        Birthdate = model.registermodel.Birthdate
                    });

                WebSecurity.Login(model.registermodel.UserName, model.registermodel.Password);
                return RedirectToAction("Index", "Home");
            }
            catch (MembershipCreateUserException e)
            {
                ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
            }
        }

        // If we got this far, something failed, redisplay form
        return RedirectToAction("Register", "Home", model);
    }

因此,modelstate.isvalid应该失败,它会重定向到home控制器和register方法并发送模型。这里一切正常,模型包含数据。但是当我重定向到另一个控制器时

     public ActionResult Register(SignUpLoginModel model) 
    {
        ViewBag.Message = "RegisterFail";
        return View("Index", "Home", model);
    }

我的模型以null而不是正确的数据结束。我做错了什么?

1 个答案:

答案 0 :(得分:0)

我很确定这是因为RedirectToAction(您使用的过载和任何其他签名都没有)不会为您转发模型。它会向您的浏览器发回302,然后向新的网址发出新的GET请求 - 因此您的模型数据会丢失。

所以你需要在第一个控制器中做这样的事情

{
   TempData["signupModel"]=model;       
   return RedirectToAction("Register", "Home", model);       
}

然后在重定向控制器中:

public ActionResult Register(SignUpLoginModel model) 
    {
        ViewBag.Message = "RegisterFail";
        return View("Index", "Home", TempData["signupModel"]);
    }

但是我不明白为什么你不是第一次直接返回一个视图,为什么你需要重定向 - 因为从你的代码中你似乎只是重定向回同一个控制器 - 或者我错过了什么吗?

根据以下评论进行编辑

老实说,我认为你最好使用Ajax,因为你要做的就是在多个控制器/视图中保持状态,这对于MVC来说并不是真正的惯用语。

如果您通过Ajax提交“注册”弹出窗体,那么您实际上永远不会离开索引页面,只需执行一些代码服务器端并返回一些JSON来指示您的注册是否正常。当此响应指示错误时,您只能在弹出窗体上显示错误消息,否则您可以重定向到客户端的任何位置。

OR

当您的Register控制器确定注册失败时,请返回主页索引视图,例如

ViewBag.Message = "RegisterFail";
return View("~/HomePage/HomeController/Index.cshtml", model); //or whatever the virtual path to the home page view is

但是我不喜欢这种方法,因为我觉得你的注册表格HTML是由主页视图在线生成的,这对我来说听起来很混乱。