【问题标题】:System.Net.Http.HttpClient instance throws an exception when setting a comma. Why?System.Net.Http.HttpClient 实例设置逗号时抛出异常。为什么?
【发布时间】:2014-02-17 09:06:52
【问题描述】:

鉴于以下System.Net.Http.HttpClient Portable Class Library 抛出异常:

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

例外情况是:格式无效

在 System.Net.Http.Headers.HttpHeaders.AddInternal (System.String 名称,IEnumerable1 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, IEnumerable1 值)[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 名称, System.String 值)[0x00000] 中 /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders

现在这只发生在以下情况下

标题键 = Authorization。如果你把它改成别的,没关系。 Value = 必须有一个逗号。

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

谁能解释这是怎么回事?

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

更新:

这是一张照片。

【问题讨论】:

  • 那是堆栈跟踪,有什么异常?
  • 已更新。哎呀。关于那个。
  • 异常表明它是无效的格式。为什么要在该标题中设置逗号?
  • @CodeCaster 因为我想并且相信/相信它是有效的。

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


【解决方案1】:

根据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");

【讨论】:

  • 但我想为 Authorization 字段设置的值是 'aaa,bbb' .. 不是键/值结果。然后,只有我的服务器,我用逗号分割那个 value 并假设第一段是 Foo 而第二段是 Bah。
  • 好吧,你不能,你必须想点别的。也许您可以对值进行 base64 编码。
  • 这仅适用于 AUTHORIZATION 标头吗?或 -any- 标题?
  • 如果你想要一个你指定格式的标题然后创建一个自定义标题,但是这种方法存在缓存控制问题,或者只是放置一些虚拟数据使其成为键值对,例如1=aaaa, 2=bbbb
  • @Pure.Krome auth 参数可以是名称/值对,也可以是逗号不是有效字符的 token68 值。见这里tools.ietf.org/html/draft-ietf-httpbis-p7-auth-26#section-2.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 [ 和 ]。

【讨论】:

  • 请注意,在更新了 Mono(版本 5)的较新 Android 上,上述代码将失败。它不再需要。如果您确实需要支持较旧的 Mono 框架,请在使用答案之前对版本 >5 进行测试。
猜你喜欢
  • 2013-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
  • 2010-10-12
  • 1970-01-01
  • 2012-09-12
  • 2017-09-21
相关资源
最近更新 更多