We have an IHttpHandler
for stylesheets and add a <link/>
tag to the page like this:
HtmlGenericControl link = new HtmlGenericControl("link");
link.Attributes.Add("rel", "stylesheet");
link.Attributes.Add("href", "stylesheet.axd?d=" +
HttpServerUtility.UrlTokenEncode(token));
head.Controls.Add(link);
In the stylesheet.axd
handler, we UrlTokenDecode
the d
query string parameter like this:
var token = HttpServerUtility.UrlTokenDecode(Request.QueryString["d"]);
This works most of the time but every now and then we find one of the following two exceptions in our log:
[FormatException: Invalid character in a Base-64 string.]
System.Convert.FromBase64CharArray(Char[] inArray, Int32 offset, Int32 length)
System.Web.HttpServerUtility.UrlTokenDecode(String input)
...
[FormatException: Invalid length for a Base-64 char array.]
System.Convert.FromBase64CharArray(Char[] inArray, Int32 offset, Int32 length)
System.Web.HttpServerUtility.UrlTokenDecode(String input)
System.Web.HttpServerUtilityWrapper.UrlTokenDecode(String input)
...
Any ideas what would cause this phenomenon?
Remarks:
- the resulting URL is < 1500, so below any known URL limits (e.g. IE: 2083)
- seems to be independent of user agent (we have these exceptions for IE6,7,8, FF & Chrome)
- our (unconfirmed) suspicions include AntiVirus products, HTTP proxies, browser addons
- found this remotely related question, but it's about a viewstate issue
We had similar problems, so we avoided UrlTokenEncode, the reason is base64 sometimes pads trailing characters as '==' and so on, so they dont get transmitted in url correctly. And I think there is a bug in .NET, however we changed it to following and it started working.
We did this way and it worked always.
and at receiving side, we use only
We do not need to use UrlDecode, because the query string object stores information in decoded format already.
UrlTokenDecode
andUrlTokenEncode
do not actually decode/encode base64url, but can be used for it anyway with some additions. Also, there are alternatives which may or may not be better.See C#: base64url according to RFC4648