MVC Post导致QueryString在重新加载相同视图时丢失

时间:2014-07-17 12:45:53

标签: c# asp.net asp.net-mvc asp.net-mvc-4 post

请让我解释一下设置。

我有一个更改密码控制器/操作和视图。 以下是我的帐户控制器中的操作签名:

public ActionResult ChangePassword(ChangePasswordMessageId? message)

[HttpPost]
public ActionResult ChangePassword(ChangePasswordViewModel model)

首次加载更改密码时,我在查询字符串中有一些数据。这是一个例子:

https://www.mywebsite.com/Account/ChangePassword?mobile=1

以下是视图中的表单声明。

@using (Html.BeginForm("ChangePassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()

使用简单的提交按钮提交表单:

<div class="form-group">
  <div class="col-md-offset-2 col-md-4">
    <input type="submit" value="Change Password" class="btn btn-primary btn-block" />
  </div>
</div>

表单有3个字段:当前密码,新密码和确认密码。 如果用户正确填写所有数据,并通过所有客户端验证,表单工作正常。除了一个用例外,一切正常。

假设用户输入了不正确的旧密码值。当我进入上面的HTTPPOST ChangePassword操作时,它将失败。这就是代码的样子。

[HttpPost]
            public ActionResult ChangePassword(ChangePasswordViewModel model)
            {   
                if (ModelState.IsValid)
                {
                    try
                    {
                        MembershipUser user = Membership.GetUser();
        //The NEXT line is the one that fails if they supply the wrong Old Password value.
        //The code then falls to the catch condition below.
                        bool changePassword = user.ChangePassword(model.OldPassword, model.NewPassword);
                        if (changePassword)
                        {
                            string path = Url.Action("ChangePassword", new { Message = ChangePasswordMessageId.ChangePasswordSuccess });
                            temp = Request.UrlReferrer.ToString();
                            pos = temp.IndexOf("?");
                            if (pos > 0) path += "&" + temp.Substring(pos + 1);
                            return RedirectToLocal(path);    
                       }
                        else
                        {
                            ModelState.AddModelError("", "Change Password failed.");
                        }
                    }
                    catch //(Exception ex)
                    {
                        ModelState.AddModelError("", "Change Password failed.");
                        //ModelState.AddModelError("", ex.Message);
                    }
                }

                // If we got this far, something failed, redisplay form
    //The original query string will be gone. The URLwill now only show
    //https://www.mywebsite.com/Account/ChangePassword
                return View(model);
            }

是否可以打电话&#34;返回View(型号);&#34;那么原始查询字符串仍然存在? 我需要在页面之间维护查询字符串。除了这个用例外,我在任何地方都可以使用它。

谢谢!

6 个答案:

答案 0 :(得分:7)

如果有人仍在寻找此解决方案,请尝试不提供控制器和操作名称。

 @using (Html.BeginForm(null, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
    {
        @Html.AntiForgeryToken()

答案 1 :(得分:1)

您可以采用的一种方法是将Mobile标记作为视图模型的一部分。并且,在Get控制器操作中,确保在填充View模型时从查询字符串中获取Mobile标记。

在表单上,​​为要回发的字段创建隐藏的输入字段。 E.g:

@Html.Hidden(Model.Mobile)

在发布后,Mobile值将在ChangePasswordViewModel中正确设置,以便您可以访问它。

答案 2 :(得分:0)

return RedirectToAction("Index", Request.QueryString.ToRouteValues());

答案 3 :(得分:0)

我的代码在VB中,在视图中,创建一个帮助函数将所有URL查询参数加载到表单中:

@Functions
Public Function GetRouteValues() As RouteValueDictionary
    Dim RouteValues As New RouteValueDictionary
    For Each Qstr As String In Request.QueryString
        RouteValues.Add(Qstr, Request.QueryString.GetValues(Qstr).FirstOrDefault)
    Next
    Return RouteValues
End Function
End Functions

然后将表单头声明为以下

@Using (Html.BeginForm("MultipleHandler", "Files", GetRouteValues, FormMethod.Post))

这样,您就将查询字符串集合传递给了操作。

在动作中,使用相同的功能:

Private Function AllRouteVlaues() As RouteValueDictionary
        Dim RouteValues As New RouteValueDictionary
        For Each Qstr As String In Request.QueryString
            RouteValues.Add(Qstr, Request.QueryString.GetValues(Qstr).FirstOrDefault)
        Next
        Return RouteValues
    End Function

用法:

Return RedirectToAction("Index", AllRouteVlaues)

希望有所帮助:)

答案 4 :(得分:0)

尝试一下:

using (Html.BeginForm("Action", "Controller",  new { Var1 = (string)ViewBag.Var1, Var2 = (string)ViewBag.Var2, Var3 = (string)ViewBag.Var3 }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                    {

答案 5 :(得分:-1)

您需要在“某种程度上”在新请求中包含查询字符串参数 在路上将是以下(这也是MS在他们的示例中使用ReturnUrl的方式):

public ActionResult ChangePassword(ChangePasswordMessageId? message. int mobile = 0)
{
    // your code
    ViewBag.Mobile = mobile;
    return View();
}
[HttpPost]
public ActionResult ChangePassword(ChangePasswordViewModel model, int mobile = 0)
{
    // your code
    ViewBag.Mobile = mobile;
    return View(model);
}

@using (Html.BeginForm("ChangePassword", "Account", FormMethod.Post, 
    new { @class = "form-horizontal", role = "form", mobile = @ViewBag.Mobile }))