C# HttpClient检索所有标头

C# HttpClient检索所有标头,c#,http,http-headers,windows-phone-8,dotnet-httpclient,C#,Http,Http Headers,Windows Phone 8,Dotnet Httpclient,目前,我正在开发API包装器。如果我发送了错误的消费者密钥,服务器将在标题中返回状态为403禁止。它还将传递自定义标题。如何实际检索这些自定义标题 这是从服务器接收的响应 Cache-Control: private Date: Wed, 01 May 2013 14:36:17 GMT P3P: policyref="/w3c/p3p.xml", CP="ALL CURa ADMa DEVa OUR IND UNI COM NAV INT STA PRE" Server: Apache/2

目前,我正在开发API包装器。如果我发送了错误的
消费者密钥
,服务器将在标题中返回
状态
403禁止
。它还将传递自定义标题。如何实际检索这些自定义标题

这是从服务器接收的响应

Cache-Control: private
Date: Wed,  01 May 2013 14:36:17 GMT
P3P: policyref="/w3c/p3p.xml",  CP="ALL CURa ADMa DEVa OUR IND UNI COM NAV INT STA PRE"
Server: Apache/2.2.23 (Amazon)
Status: 403 Forbidden
X-Error: Invalid consumer key.
X-Error-Code: 152
X-Powered-By: PHP/5.3.20
Connection: keep-alive
我需要检索
X-Error
X-Error-code
。目前,我正在使用
HttpClient
类来处理请求。如果我在VS Studio 2012的Quick watch下观看标题响应,我会发现它是这样的

((System.Net.Http.Headers.HttpHeaders)(response.Headers)).headerStore[“X-Error-code”].ParsedValue

还有别的办法吗

编辑:
headerStore
无法通过代码访问,因为这是私有字段。我只能通过快速观察窗口访问它

这是我的请求片段:

var response = await _httpClient.PostAsync("/v3/oauth/request", content);
返回一个引用,因此您应该能够使用


只是我在试图查找不存在的标题时发现的一个问题。您应该使用TryGetValues而不是GetValues,因为在运行时,如果找不到标头,它将引发异常。您可以使用类似以下代码的内容:

IEnumerable<string> cookieHeader; 
response.Headers.TryGetValues("Set-Cookie", out cookieHeader);
IEnumerable cookieHeader;
response.Headers.TryGetValues(“设置Cookie”,out-cookieHeader);

由于问题的标题是“检索所有标题”,因此我想添加一个与此相关的答案

HttpClient
方法返回的有两个头属性:

  • HttpResponseMessage.Headers
    是一个具有通用响应头的
  • HttpResponseMessage.Content.Headers
    是一个具有特定于内容的头的
这两个对象都实现了
IEnumerable,这对我很有用:

(String[])response.Headers.GetValues("X-Error"))[0]

有点笨重,但很容易理解

            System.Diagnostics.Debug.Write("----- CLIENT HEADERS -----" + Environment.NewLine);
            foreach (KeyValuePair<string, IEnumerable<string>> myHeader in myHttpClient.DefaultRequestHeaders)
            {
                System.Diagnostics.Debug.Write(myHeader.Key + Environment.NewLine);
                foreach(string myValue in myHeader.Value)
                {
                    System.Diagnostics.Debug.Write("\t" + myValue + Environment.NewLine);
                }
            }

            System.Diagnostics.Debug.Write("----- MESSAGE HEADERS -----" + Environment.NewLine);
            foreach (KeyValuePair<string, IEnumerable<string>> myHeader in myHttpRequestMessage.Headers)
            {
                System.Diagnostics.Debug.Write(myHeader.Key + Environment.NewLine);
                foreach (string myValue in myHeader.Value)
                {
                    System.Diagnostics.Debug.Write("\t" + myValue + Environment.NewLine);
                }
            }

            System.Diagnostics.Debug.Write("----- CONTENT HEADERS -----" + Environment.NewLine);
            foreach (KeyValuePair<string, IEnumerable<string>> myHeader in myHttpRequestMessage.Content.Headers)
            {
                System.Diagnostics.Debug.Write(myHeader.Key + Environment.NewLine);
                foreach (string myValue in myHeader.Value)
                {
                    System.Diagnostics.Debug.Write("\t" + myValue + Environment.NewLine);
                }
            }
System.Diagnostics.Debug.Write(“----客户机头----”+Environment.NewLine);
foreach(myHttpClient.DefaultRequestHeaders中的KeyValuePair myHeader)
{
System.Diagnostics.Debug.Write(myHeader.Key+Environment.NewLine);
foreach(myHeader.Value中的字符串myValue)
{
System.Diagnostics.Debug.Write(“\t”+myValue+Environment.NewLine);
}
}
System.Diagnostics.Debug.Write(“----消息头----”+Environment.NewLine);
foreach(myHttpRequestMessage.Headers中的KeyValuePair myHeader)
{
System.Diagnostics.Debug.Write(myHeader.Key+Environment.NewLine);
foreach(myHeader.Value中的字符串myValue)
{
System.Diagnostics.Debug.Write(“\t”+myValue+Environment.NewLine);
}
}
System.Diagnostics.Debug.Write(“----CONTENT-HEADERS-----”+Environment.NewLine);
foreach(myHttpRequestMessage.Content.Headers中的KeyValuePair myHeader)
{
System.Diagnostics.Debug.Write(myHeader.Key+Environment.NewLine);
foreach(myHeader.Value中的字符串myValue)
{
System.Diagnostics.Debug.Write(“\t”+myValue+Environment.NewLine);
}
}

不,我不能这样做,因为我会收到此错误
错误3无法将带[]的索引应用于System.Net.Http.Headers.HttpResponseHeaders'类型的表达式。
。为了清晰起见,我将更新上面的代码。@ShulhiSapli:Ah-没有发现它是
HttpClient
。将进行编辑。如果需要更多详细信息,可以在此处查看,这将为headers变量创建一个非常复杂的类型。如何将数据输出到一个字符串或一个简单的集合?@jamiemashall因为它将所有内容放入一个键/值对的IEnumerable中,所以您应该能够使用foreach循环遍历组合列表。每对的键是标题名,每对的值是标题值列表。值得注意的是,要使
Concat
正常工作,您需要确保使用System.Linq包含
我很好奇为什么投票否决了这辆日产汽车。我把它作为我正在使用的一个控制台应用程序的its包含在这里。我对此也投了反对票,因为它不安全:
HttpHeaders
的规范不能保证
.GetValues(String)
将返回一个
String[]
(它只说它返回一个
IEnumerable
),如果指定的名称没有值,那么您将得到一个
InvalidOperationException
——如果重复相同的头,那么这将只返回指定头名称的第一个值。对此答案进行否决表决的另一个原因是OP询问如何获取“所有头”但是这个答案只返回一个命名头的值——所以这根本不能回答最初的问题。
    HttpResponseMessage resp = await httpClient.GetAsync( url );

    String allHeaders = Enumerable
        .Empty<(String name, String value)>()
        // Add the main Response headers as a flat list of value-tuples with potentially duplicate `name` values:
        .Concat(
            resp.Headers
                .SelectMany( kvp => kvp.Value
                    .Select( v => ( name: kvp.Key, value: v ) )
                )
        )
         // Concat with the content-specific headers as a flat list of value-tuples with potentially duplicate `name` values:
        .Concat(
            resp.Content.Headers
                .SelectMany( kvp => kvp.Value
                    .Select( v => ( name: kvp.Key, value: v ) )
                )
        )
        // Render to a string:
        .Aggregate(
            seed: new StringBuilder(),
            func: ( sb, pair ) => sb.Append( pair.name ).Append( ": " ).Append( pair.value ).AppendLine(),
            resultSelector: sb => sb.ToString()
        );
    HttpResponseMessage resp = await httpClient.GetAsync( url );

    NameValueCollection allHeaders = Enumerable
        .Empty<(String name, String value)>()
        // Add the main Response headers as a flat list of value-tuples with potentially duplicate `name` values:
        .Concat(
            resp.Headers
                .SelectMany( kvp => kvp.Value
                    .Select( v => ( name: kvp.Key, value: v ) )
                )
        )
         // Concat with the content-specific headers as a flat list of value-tuples with potentially duplicate `name` values:
        .Concat(
            resp.Content.Headers
                .SelectMany( kvp => kvp.Value
                    .Select( v => ( name: kvp.Key, value: v ) )
                )
        )
        .Aggregate(
            seed: new NameValueCollection(),
            func: ( nvc, pair ) => { nvc.Add( pair.name, pair.value ); return nvc; },
            resultSelector: nvc => nvc
        );
(String[])response.Headers.GetValues("X-Error"))[0]
            System.Diagnostics.Debug.Write("----- CLIENT HEADERS -----" + Environment.NewLine);
            foreach (KeyValuePair<string, IEnumerable<string>> myHeader in myHttpClient.DefaultRequestHeaders)
            {
                System.Diagnostics.Debug.Write(myHeader.Key + Environment.NewLine);
                foreach(string myValue in myHeader.Value)
                {
                    System.Diagnostics.Debug.Write("\t" + myValue + Environment.NewLine);
                }
            }

            System.Diagnostics.Debug.Write("----- MESSAGE HEADERS -----" + Environment.NewLine);
            foreach (KeyValuePair<string, IEnumerable<string>> myHeader in myHttpRequestMessage.Headers)
            {
                System.Diagnostics.Debug.Write(myHeader.Key + Environment.NewLine);
                foreach (string myValue in myHeader.Value)
                {
                    System.Diagnostics.Debug.Write("\t" + myValue + Environment.NewLine);
                }
            }

            System.Diagnostics.Debug.Write("----- CONTENT HEADERS -----" + Environment.NewLine);
            foreach (KeyValuePair<string, IEnumerable<string>> myHeader in myHttpRequestMessage.Content.Headers)
            {
                System.Diagnostics.Debug.Write(myHeader.Key + Environment.NewLine);
                foreach (string myValue in myHeader.Value)
                {
                    System.Diagnostics.Debug.Write("\t" + myValue + Environment.NewLine);
                }
            }