I'm trying to pass ReturnUrl
query string to my login page. I have a partial Login view (kind of like a login box) and a login view. Right now, I have the following line in my partial view:
using (Html.BeginForm("Login"
, "Account"
, new { returnUrl=HttpUtility.UrlEncode(
Request.QueryString["ReturnUrl"])
?? HttpUtility.UrlEncode(Request.Path)
}
, FormMethod.Post))
When I click on my partial view's submit button(e.g. from
http://localhost:12345/Product/1234/Product1
),
I'll get redirected to my login page with the following url:
http://localhost:12345/Account/Login?returnUrl=%2FProduct%2F1234%2FProduct1
But if I log on, I'll see an http 400 response, because the page is returning to
http://localhost:12345/Account/%2fProduct%2f1234%2fproduct1
.
Also, if I type in the wrong credentials, I cause the returnUrl
query string to be encoded again thus every %
character is converted to %25
again!
I should mention if I manually type in
http://localhost:12345/Account/Login?returnUrl=/Product/1234/Product1
(without encoding) and log in, I'm successfully redirected to the specified path.
I guess I'm missing something obvious. But couldn't find out what.
Thanks.
You don't need to encode it when you pass it to Html.BeginForm()
Just use the value without encoding it as it is encoded by the TagBuilder
when assigning the value to the action
attribute of the generated <form>
element
@using(Html.BeginForm(
"Login",
"Account",
new { returnUrl= Request.QueryString["ReturnUrl"] },
FormMethod.Post)) {
@* form here *@
}
I've removed the null-coalescing operator and Request.Path
too because if ReturnUrl
is null, it's not going to matter to the generated url assigned to the action
attribute (assuming it's an optional parameter in your routing, or an optional property on your ViewModel).
The relevant source code in TagBuilder
is (comment mine)
private void AppendAttributes(StringBuilder sb) {
foreach (var attribute in Attributes) {
string key = attribute.Key;
if (String.Equals(key, "id", StringComparison.Ordinal /* case-sensitive */) && String.IsNullOrEmpty(attribute.Value)) {
continue; // DevDiv Bugs #227595: don't output empty IDs
}
// ---------------------------------------
// Value will be HTML attribute encoded by
// the Encoder set for the application
// ---------------------------------------
string value = HttpUtility.HtmlAttributeEncode(attribute.Value);
sb.Append(' ')
.Append(key)
.Append("=\"")
.Append(value)
.Append('"');
}
}