Please let me explain the setup.
I have a Change Password Controller/Action and View. Here are the Action Signatures in my Account Controller:
public ActionResult ChangePassword(ChangePasswordMessageId? message)
[HttpPost]
public ActionResult ChangePassword(ChangePasswordViewModel model)
When change password is first loaded, I have some data in the querystring. Here is an example:
https://www.mywebsite.com/Account/ChangePassword?mobile=1
Here is the Form declaration from the view.
@using (Html.BeginForm("ChangePassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
The form is submitted with a simple submit button:
<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>
The form has 3 fields: Current Password, New Password, and Confirm Password. If the user fills in all the data correctly, and passes all the client side validation the form works fine. Everything works fine except for one use case.
Suppose the user enters an Old Password value that is not correct. When I get to the HTTPPOST ChangePassword action above, it will fail. This is what that code looks like.
[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);
}
Is there away to call "return View(model);" so that the original query string will still be there? I need to maintain the query string from page to page. I have it working everywhere except for this one use case.
Thanks!
If somebody is still looking for this solution, try not supplying controller and action names.
@using (Html.BeginForm(null, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
One way you could do it is to make your Mobile
flag part of your View Model. And, in your Get controller action, make sure you get the Mobile flag from your query string when you populate your View Model.
On your form, create a hidden input field for the fields you want posted back. E.g.:
@Html.Hidden(Model.Mobile)
On post, the Mobile
value will be set correctly in your ChangePasswordViewModel
so you have access to it.
return RedirectToAction("Index", Request.QueryString.ToRouteValues());
My code is in VB, in the view, create a helper function to load all URL query parameters into the form:
@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
then declare the form head as following
@Using (Html.BeginForm("MultipleHandler", "Files", GetRouteValues, FormMethod.Post))
This way, you passed your collection of query string to the action.
In the action, use the same function:
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
Usage:
Return RedirectToAction("Index", AllRouteVlaues)
Hope that helps :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With