'Invalid non-ASCII or control character in header on redirect

I'm using asp.net core 2.1 and I have a problem on redirect. My URL is like:

HTTP://localhost:60695/ShowProduct/2/شال-آبی

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:

HTTP://localhost:60695/ShowProduct/2/scarf-blue

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?



Solution 1:[1]

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= "http://localhost:60695";
var path = "/ShowProduct/2/???-???";
path=String.Join(
    "/",
    path.Split("/").Select(s => System.Net.WebUtility.UrlEncode(s))
);
return Redirect(host+path);

Solution 2:[2]

Another simpler option (works for me):

    var uri = new Uri(urlStr);
    return Redirect(uri.AbsoluteUri);

Solution 3:[3]

I use Flurl

var encoded = Flurl.Url.EncodeIllegalCharacters(url);
return base.Redirect(encoded);

This works well for absolute and relative URLs.

Solution 4:[4]

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));
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Offir
Solution 2 hex
Solution 3 DevCorvette
Solution 4 Smok3r