2015-04-03 33 views
0

有点背景: 我试图将一个android应用“移植”到调用非开放式Web API的Windows Phone。由于API没有打开或记录,我使用Fiddler,运行应用程序的Android版本,并监听它所做的API调用。通用应用程序HttpClient头文件:如何禁用某些头文件?

我使用Windows.Web.Http.HttpClient作为选择的类,因为它看起来像这将是类移动而不是System.Net.Http.HttpClient。

下面是我用它来生成一个HTTP POST请求的C#代码摘录:

HttpBaseProtocolFilter _httpFilter = new HttpBaseProtocolFilter(); 
HttpClient _httpClient = new HttpClient(_httpFilter);      
_httpClient.DefaultRequestHeaders.AcceptEncoding.Clear(); 
_httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/xml"); 
_httpClient.DefaultRequestHeaders.AcceptLanguage.TryParseAdd("en");    
_httpClient.DefaultRequestHeaders.Connection.TryParseAdd("Keep-Alive"); 
_httpClient.DefaultRequestHeaders.Add("message-version", "1"); 
_httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd("Android|SAMSUNG- SGH-I337|3.3.1"); 
_httpClient.DefaultRequestHeaders.Cookie.TryParseAdd(cookie); //Some cookie values         

Uri uri = new Uri(SOMEURI); 
XDocument xd = new XDocument(STUFF_TO_BUILD_XML); 
string xd_str = string.Concat(xd.Declaration.ToString(), xd.ToString()); 
xd_str = xd_str.Replace("\r\n", string.Empty); 
xd_str = xd_str.Replace(" ", string.Empty); 
HttpRequestMessage req_msg = new HttpRequestMessage(HttpMethod.Post, uri); 
HttpStringContent strcnt = new HttpStringContent(xd_str);    
req_msg.Content = strcnt; 
req_msg.Content.Headers.ContentType = new  Windows.Web.Http.Headers.HttpMediaTypeHeaderValue("text/xml; charset=UTF-8"); 
req_msg.Headers.Host = new Windows.Networking.HostName(SOMEHOSTNAME); 

HttpResponseMessage rsp_msg = await _httpClient.SendRequestAsync(req_msg); 

这里的原始文本使用我的代码使API调用时菲德勒认为:

POST <HTTPS endpoint> HTTP/1.1 
Connection: Keep-Alive 
Accept-Encoding: gzip, deflate 
Host: <hostname> 
Cookie2: Version=1 
Accept: application/xml 
message-version: 1 
User-Agent: Android|SAMSUNG-SGH-I337|3.3.1 
Accept-Language: en 
Content-Length: 173 
Content-Type: text/xml; charset=UTF-8 
Cache-Control: no-cache 
Cookie: STR1=VAL1; STR2=VAL2 

<MESSAGE_IN_XML> 

--Response-- 
HTTP/1.1 401 Unauthorized 
Server: Apache-Coyote/1.1 
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1 
X-Frame-Options: SAMEORIGIN 
Transfer-Encoding: chunked 
Date: Fri, 03 Apr 2015 01:18:07 GMT 

0 

这里的原始文本提琴手通过Android应用程序发出请求时看到:

POST <HTTPS endpoint> HTTP/1.1 
Content-Type: text/xml; charset=UTF-8 
Connection: Keep-Alive 
accept: application/xml 
user-agent: Android|SAMSUNG-SGH-I337|3.4 
message-version: 1 
Accept-Language: en 
Content-Length: 173 
Host: <hostname> 
Cookie: STR1=VAL1; STR2=VAL2 
Cookie2: $Version=1 

<MESSAGE_IN_XML> 

--response-- 
HTTP/1.1 200 OK 
Server: Apache-Coyote/1.1 
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1 
X-Frame-Options: SAMEORIGIN 
Content-Type: application/xml;charset=utf-8 
Date: Fri, 03 Apr 2015 01:08:22 GMT 
Content-Length: 364 

<MESSAGE_IN_XML> 

请参阅Fiddler的输出,我看到的唯一区别是头部中的Accept-Encoding和Cache-Control条目。有没有办法不发送它们?或者我在这里错过了什么?

回答

0

您应该发送授权标头。

样品:Authorization: Basic àaaaaaaa

,将解决未授权的问题。

说明:

我们有几种方式,以确保服务的被提供给公众。最常用的方法是通过授权头将凭据从客户端应用程序传递到目标应用程序。

授权头被客户端添加到请求中。在C#中,我们通常使用AuthenticationHeaderValue

示例可以在这里找到。

http://leastprivilege.com/2012/03/14/asp-net-webapi-security-4-examples-for-various-authentication-scenarios/

+0

请您详细说明一下吗?我不熟悉c#/通用应用程序或一般软件,因此任何细节都有帮助。谢谢 – hxdai 2015-04-03 03:50:52

+0

最完美的学习资源来自规范。 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.8。如果尽管设置了授权头文件,但您仍然可以获得401,请参阅api文档以获取正确的方式,因为有些可能仍需要来自请求有效内容(主体)的身份验证信息, – Saravanan 2015-04-03 04:04:23

0

我Saravanan的分析一致,这个问题“似乎”是相关的授权请求,但是,你问的是如何禁用某些标题(我不会做一个判断是否这是“正确”,没有更多的上下文,你正在做什么),所以...

你可以“fudge”HttpClient类通过使用继承来创建自己的版本,因为我在System.Net.Http.HttpClient本身中看不到任何代码(即使在.NET Reference源代码中,奇怪)我必须使用一些技巧创建我自己的版本(实例化基类对象,然后赋值es使用基于密封的HttpRequestHeaders类创建的第二个自定义类)。

将此类添加到您的项目中,然后您想要将代码中的HttpClient引用替换为MyHttpClient ...以下是可用于删除这些头的类(Accept-Encoding和Cache-Control) ,我已经在Fiddler中进行了测试,以便仔细检查它的工作原理:

public class MyHttpClient : HttpClient 
{   

    public MyHttpClient(HttpClientHandler handler) : base(handler) { 
     DefaultRequestHeaders = new MyHttpRequestHeaders(); 
    } 

    // 
    // Summary: 
    //  Gets or Sets the headers which should be sent with each request. 
    // 
    // Returns: 
    //  Returns The headers which should 
    //  be sent with each request. 
    public new MyHttpRequestHeaders DefaultRequestHeaders { get; set; } 
} 

public class MyHttpRequestHeaders : HttpHeaders 
{ 
    public MyHttpRequestHeaders() 
    { 
     HttpClient client = new HttpClient(); 
     this.Accept = client.DefaultRequestHeaders.Accept; 
     this.AcceptCharset = client.DefaultRequestHeaders.AcceptCharset; 
     this.AcceptLanguage = client.DefaultRequestHeaders.AcceptLanguage; 
     this.Authorization = client.DefaultRequestHeaders.Authorization; 
     this.Connection = client.DefaultRequestHeaders.Connection; 
     this.ConnectionClose = client.DefaultRequestHeaders.ConnectionClose; 
     this.Date = client.DefaultRequestHeaders.Date; 
     this.Expect = client.DefaultRequestHeaders.Expect; 
     this.ExpectContinue = client.DefaultRequestHeaders.ExpectContinue; 
     this.From = client.DefaultRequestHeaders.From; 
     this.Host = client.DefaultRequestHeaders.Host; 
     this.IfMatch = client.DefaultRequestHeaders.IfMatch; 
     this.IfModifiedSince = client.DefaultRequestHeaders.IfModifiedSince; 
     this.IfNoneMatch = client.DefaultRequestHeaders.IfNoneMatch; 
     this.IfRange = client.DefaultRequestHeaders.IfRange; 
     this.IfUnmodifiedSince = client.DefaultRequestHeaders.IfUnmodifiedSince; 
     this.MaxForwards = client.DefaultRequestHeaders.MaxForwards; 
     this.Pragma = client.DefaultRequestHeaders.Pragma; 
     this.ProxyAuthorization = client.DefaultRequestHeaders.ProxyAuthorization; 
     this.Range = client.DefaultRequestHeaders.Range; 
     this.Referrer = client.DefaultRequestHeaders.Referrer; 
     this.TE = client.DefaultRequestHeaders.TE; 
     this.Trailer = client.DefaultRequestHeaders.Trailer; 
     this.TransferEncoding = client.DefaultRequestHeaders.TransferEncoding; 
     this.TransferEncodingChunked = client.DefaultRequestHeaders.TransferEncodingChunked; 
     this.Upgrade = client.DefaultRequestHeaders.Upgrade; 
     this.UserAgent = client.DefaultRequestHeaders.UserAgent; 
     this.Via = client.DefaultRequestHeaders.Via; 
     this.Warning = client.DefaultRequestHeaders.Warning; 
    } 

    // Summary: 
    //  Gets the value of the Accept header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Accept header for an HTTP request. 
    public HttpHeaderValueCollection<MediaTypeWithQualityHeaderValue> Accept { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Accept-Charset header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Accept-Charset header for an HTTP request. 
    public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptCharset { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Accept-Language header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Accept-Language header for an HTTP request. 
    public HttpHeaderValueCollection<StringWithQualityHeaderValue> AcceptLanguage { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the Authorization header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.AuthenticationHeaderValue.The value of the 
    //  Authorization header for an HTTP request. 
    public AuthenticationHeaderValue Authorization { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Connection header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Connection header for an HTTP request. 
    public HttpHeaderValueCollection<string> Connection { get; set; } 
    // 
    // Summary: 
    //  Gets or sets a value that indicates if the Connection header for an HTTP 
    //  request contains Close. 
    // 
    // Returns: 
    //  Returns System.Boolean.true if the Connection header contains Close, otherwise 
    //  false. 
    public bool? ConnectionClose { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the Date header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.DateTimeOffset.The value of the Date header for an HTTP request. 
    public DateTimeOffset? Date { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Expect header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Expect header for an HTTP request. 
    public HttpHeaderValueCollection<NameValueWithParametersHeaderValue> Expect { get; set; } 
    // 
    // Summary: 
    //  Gets or sets a value that indicates if the Expect header for an HTTP request 
    //  contains Continue. 
    // 
    // Returns: 
    //  Returns System.Boolean.true if the Expect header contains Continue, otherwise 
    //  false. 
    public bool? ExpectContinue { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the From header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.String.The value of the From header for an HTTP request. 
    public string From { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the Host header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.String.The value of the Host header for an HTTP request. 
    public string Host { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the If-Match header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the If-Match header for an HTTP request. 
    public HttpHeaderValueCollection<EntityTagHeaderValue> IfMatch { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the If-Modified-Since header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.DateTimeOffset.The value of the If-Modified-Since header for 
    //  an HTTP request. 
    public DateTimeOffset? IfModifiedSince { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the If-None-Match header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.Gets the value 
    //  of the If-None-Match header for an HTTP request. 
    public HttpHeaderValueCollection<EntityTagHeaderValue> IfNoneMatch { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the If-Range header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.RangeConditionHeaderValue.The value of the 
    //  If-Range header for an HTTP request. 
    public RangeConditionHeaderValue IfRange { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the If-Unmodified-Since header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.DateTimeOffset.The value of the If-Unmodified-Since header 
    //  for an HTTP request. 
    public DateTimeOffset? IfUnmodifiedSince { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the Max-Forwards header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Int32.The value of the Max-Forwards header for an HTTP request. 
    public int? MaxForwards { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Pragma header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Pragma header for an HTTP request. 
    public HttpHeaderValueCollection<NameValueHeaderValue> Pragma { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the Proxy-Authorization header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.AuthenticationHeaderValue.The value of the 
    //  Proxy-Authorization header for an HTTP request. 
    public AuthenticationHeaderValue ProxyAuthorization { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the Range header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.RangeHeaderValue.The value of the Range header 
    //  for an HTTP request. 
    public RangeHeaderValue Range { get; set; } 
    // 
    // Summary: 
    //  Gets or sets the value of the Referer header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Uri.The value of the Referer header for an HTTP request. 
    public Uri Referrer { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the TE header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the TE header for an HTTP request. 
    public HttpHeaderValueCollection<TransferCodingWithQualityHeaderValue> TE { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Trailer header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Trailer header for an HTTP request. 
    public HttpHeaderValueCollection<string> Trailer { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Transfer-Encoding header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Transfer-Encoding header for an HTTP request. 
    public HttpHeaderValueCollection<TransferCodingHeaderValue> TransferEncoding { get; set; } 
    // 
    // Summary: 
    //  Gets or sets a value that indicates if the Transfer-Encoding header for an 
    //  HTTP request contains chunked. 
    // 
    // Returns: 
    //  Returns System.Boolean.true if the Transfer-Encoding header contains chunked, 
    //  otherwise false. 
    public bool? TransferEncodingChunked { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Upgrade header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Upgrade header for an HTTP request. 
    public HttpHeaderValueCollection<ProductHeaderValue> Upgrade { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the User-Agent header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the User-Agent header for an HTTP request. 
    public HttpHeaderValueCollection<ProductInfoHeaderValue> UserAgent { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Via header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Via header for an HTTP request. 
    public HttpHeaderValueCollection<ViaHeaderValue> Via { get; set; } 
    // 
    // Summary: 
    //  Gets the value of the Warning header for an HTTP request. 
    // 
    // Returns: 
    //  Returns System.Net.Http.Headers.HttpHeaderValueCollection<T>.The value of 
    //  the Warning header for an HTTP request. 
    public HttpHeaderValueCollection<WarningHeaderValue> Warning { get; set; } 
}