鉴于以下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上,所以我猜它是单声道的。不确定这是否重要。
更新:
这是一张照片。
答案 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 [和]。