设置逗号时,System.Net.Http.HttpClient实例会引发异常。为什么?

时间:2014-02-17 09:06:52

标签: c# .net http-headers dotnet-httpclient

鉴于以下System.Net.Http.HttpClient Portable Class Library会引发异常:

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Authorization", "aaaa,bbbb");

例外情况是:格式无效

  

at System.Net.Http.Headers.HttpHeaders.AddInternal(System.String)   name,IEnumerable 1 values, System.Net.Http.Headers.HeaderInfo headerInfo, Boolean ignoreInvalid) [0x0004c] in /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs:195 at System.Net.Http.Headers.HttpHeaders.Add (System.String name, IEnumerable 1个值)[0x00011] in   /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs:170   在System.Net.Http.Headers.HttpHeaders.Add(System.String name,   System.String值)[0x00000] in   /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders   < ...剪断...>

现在这只发生在以下

标题键= Authorization。如果你把它改成其他任何东西,那没关系。 值=必须有逗号。

现在,之前的SO问题表明,逗号是在标题中粘贴多个值的正确方法。

有人可以解释发生了什么吗?

注意:这是在Xamarin上,所以我猜它是单声道的。不确定这是否重要。

更新:

这是一张照片。

enter image description here

2 个答案:

答案 0 :(得分:5)

根据this links spec rfc2617,用逗号分隔确实有效。

“它使用可扩展,不区分大小写的标记来标识身份验证方案,    后跟逗号分隔的属性 - 值对列表    通过它携带实现认证所需的参数    方案“。

但其中暗示你很可能错误地设置它们,它们必须是“属性 - 值对”的形式:

auth-param     = token "=" ( token | quoted-string )

你究竟如何设置它们?

httpClient.DefaultRequestHeaders.Add("Authorization", "aaaa,bbbb");

以上看似无效,它们不是属性对“aaaa,bbbb”。您尝试设置的任一属性都没有=符号。

尝试以下测试:

httpClient.DefaultRequestHeaders.Add("Authorization", "aaaa=1234,bbbb=45678");

答案 1 :(得分:2)

单声道实现中有一个错误,它不允许标题中的有效字符,即[] - 这已得到修复,但对于Xamarin Android,它尚未达到稳定分支(它将附带Xamarin Android 5)

有可能绕过这个,如果你迫不及待,你需要现在发货,并且你需要在标题中有特殊字符,有一种方法(我现在已经废弃了)

在添加标题之前,您可以在标题中添加允许标记的字符。这是无证的,非法的(从正确的编码角度来看)并通过反射完成,但它起作用:

var assembly = typeof(System.Net.Http.Headers.HttpContentHeaders).Assembly;
var lexer = assembly.GetType("System.Net.Http.Headers.Lexer");
var field = lexer.GetField("token_chars", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
var tokens = ( bool[])field.GetValue(null);
tokens[91] = true;
tokens[93] = true;
field.SetValue(null, tokens);

在上面的示例中,我们分别允许字符91和93 [和]。