2015-04-03 37 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; } 
}