I'm using asp.net core 2.1 and I have a problem on redirect. My URL is like:
the last parameter is in Persian. and it throws below error:
InvalidOperationException: Invalid non-ASCII or control character in header: 0x0634
but when I change the last parameter in English like:
it works and everything is OK. I'm using below codes for redirecting:
[HttpPost]
[Route("Login")]
public IActionResult Login(LoginViewModel login, string returnUrl)
{
if (!ModelState.IsValid)
{
ViewBag.ReturnUrl = returnUrl;
return View(login);
}
//SignIn Codes is hidden
if (Url.IsLocalUrl(returnUrl) && !string.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
if (permissionService.CheckUserIsInRole(user.UserId, "Admin"))
{
return Redirect("/Admin/Dashboard");
}
ViewBag.IsSuccess = true;
return View();
}
how can I fix the problem?
5 Answers
General speaking, it is caused by the Redirect(returnUrl)
. This method will return a RedirectResult(url)
and finally set the Response.Headers["Location"]
as below :
Response.Headers[HeaderNames.Location] = returnUrl;
But the Headers
of HTTP doesn't accept non-ASCII characters.
There're already some issues(#2678 , #4919) suggesting to encode the URL by default. But there's no such a out-of-box function yet.
A quick fix to your issue:
var host= "";
var path = "/ShowProduct/2/شال-آبی";
path=String.Join(
"/",
path.Split("/").Select(s => System.Net.WebUtility.UrlEncode(s))
);
return Redirect(host+path);
Another simpler option (works for me):
var uri = new Uri(urlStr);
return Redirect(uri.AbsoluteUri);
The option that worked for us was to use UriHelper.Encode. This method correctly works with relative and absolute URLs and also URLs containing international domain names.
In our case URLs were always absolute and redirect code looked like:
if (Uri.TryCreate(redirectUrl, UriKind.Absolute, out var uri))
{
return Redirect(UriHelper.Encode(uri));
}
I use Flurl
var encoded = Flurl.Url.EncodeIllegalCharacters(url);
return base.Redirect(encoded);
This works well for absolute and relative URLs.
You can apply URL encoding to it for storing it on response header:
string urlEncodedValue = WebUtility.UrlEncode(value);
Vice versa to decode it:
string value = WebUtility.UrlDecode(urlEncodedValue);