The problem is that route attribute parameters won't accept any reserved characters, EVEN when they are URL-encoded:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
This will work:
https://localhost:44349/files/?fileName=mydocument%2B%23%26.docx&access_token=test-token
[Route("files/")]
[HttpGet]
public async Task<string> GetFileInfo2(string fileName, string access_token)
{
return "Test";
}
This won't work:
https://localhost:44349/files/mydocument%2B%23%26.docx?access_token=test-token
[Route("files/{fileName}/")]
[HttpGet]
public async Task<string> GetFileInfo(string fileName, string access_token)
{
return "Test";
}
Complete example from Javascript front end to C# back end with a WebClient proxy call:
Javascript:
let fileName = encodeURIComponent('mydocument+#&.docx');
fetch(`files?fileName=${fileName}&access_token=test-token`)
.then(function (response) {
return response.json();
})
.then(function (myJson) {
console.log(JSON.stringify(myJson));
});
C#:
[Route("files/")]
[HttpGet]
public async Task<string> GetFileInfo(string fileName, string access_token)
{
using (WebClient client = new WebClient())
{
var host = $"{HttpContext.Current.Request.Url.Scheme}://{HttpContext.Current.Request.Url.Host}:{HttpContext.Current.Request.Url.Port}";
var data = client.DownloadString($"{host}/proxy/files/?fileName={HttpUtility.UrlEncode(fileName)}&access_token={HttpUtility.UrlEncode(access_token)}");
return data;
}
}
[AllowAnonymous]
[Route("proxy/files/")]
[HttpGet]
public async Task<string> ProxyGetFileInfo(string fileName, string access_token)
{
return "MyValues";
}

Why these characters are disallowed and why it needs to be handled in the first place:
Excluded US-ASCII Characters disallowed within the URI syntax:
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space = <US-ASCII coded character 20 hexadecimal>
delims = "<" | ">" | "#" | "%" | <">
The character "#" is excluded because it is used to delimit a URI from a fragment identifier. The percent character "%" is excluded because it is used for the encoding of escaped characters. In other words, the "#" and "%" are reserved characters that must be used in a specific context.
List of unwise characters are allowed but may cause problems:
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
Characters that are reserved within a query component and/or have special meaning within a URI/URL:
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
The "reserved" syntax class above refers to those characters that are allowed within a URI, but which may not be allowed within a particular component of the generic URI syntax. Characters in the "reserved" set are not reserved in all contexts. The hostname, for example, can contain an optional username so it could be something like ftp://user@hostname/
where the '@' character has special meaning.
Source:
https://stackoverflow.com/a/13500078/3850405