[英]How to get the HTTP Status Code returned with WinPhone WebClient?
[英]How to get status code from webclient?
我正在使用WebClient
類將一些數據發布到Web表單。 我想獲取表單提交的響應狀態代碼。 到目前為止,我已經找到了發生異常時如何獲取狀態碼的方法
Catch wex As WebException
If TypeOf wex.Response Is HttpWebResponse Then
msgbox(DirectCast(wex.Response, HttpWebResponse).StatusCode)
End If
但是,如果表單提交成功並且沒有拋出異常,那么我將不知道狀態碼(200,301,302,...)
沒有拋出異常時,是否可以通過某種方式獲取狀態代碼?
PS:我不想使用httpwebrequest / httpwebresponse
您可以檢查錯誤的類型是否為WebException
,然后檢查響應代碼。
if (e.Error.GetType().Name == "WebException")
{
WebException we = (WebException)e.Error;
HttpWebResponse response = (System.Net.HttpWebResponse)we.Response;
if (response.StatusCode==HttpStatusCode.NotFound)
System.Diagnostics.Debug.WriteLine("Not found!");
}
要么
try
{
// send request
}
catch (WebException e)
{
// check e.Status as above etc..
}
有一種使用反射的方法。 它適用於.NET 4.0。 它訪問私有字段,並且未經修改可能無法在其他版本的.NET中使用。
我不知道為什么Microsoft不使用屬性公開此字段。
private static int GetStatusCode(WebClient client, out string statusDescription)
{
FieldInfo responseField = client.GetType().GetField("m_WebResponse", BindingFlags.Instance | BindingFlags.NonPublic);
if (responseField != null)
{
HttpWebResponse response = responseField.GetValue(client) as HttpWebResponse;
if (response != null)
{
statusDescription = response.StatusDescription;
return (int)response.StatusCode;
}
}
statusDescription = null;
return 0;
}
如果您使用的是.Net 4.0(或更低版本):
class BetterWebClient : WebClient
{
private WebRequest _Request = null;
protected override WebRequest GetWebRequest(Uri address)
{
this._Request = base.GetWebRequest(address);
if (this._Request is HttpWebRequest)
{
((HttpWebRequest)this._Request).AllowAutoRedirect = false;
}
return this._Request;
}
public HttpStatusCode StatusCode()
{
HttpStatusCode result;
if (this._Request == null)
{
throw (new InvalidOperationException("Unable to retrieve the status
code, maybe you haven't made a request yet."));
}
HttpWebResponse response = base.GetWebResponse(this._Request)
as HttpWebResponse;
if (response != null)
{
result = response.StatusCode;
}
else
{
throw (new InvalidOperationException("Unable to retrieve the status
code, maybe you haven't made a request yet."));
}
return result;
}
}
如果您使用的是.Net 4.5.X或更高版本,請切換到HttpClient :
var response = await client.GetAsync("http://www.contoso.com/");
var statusCode = response.StatusCode;
試了一下。 ResponseHeader不包含狀態碼。
如果我沒記錯的話, WebClient
能夠在一個方法調用中抽象出多個不同的請求(例如,正確處理100個Continue響應,重定向等)。 我懷疑如果不使用HttpWebRequest
和HttpWebResponse
,則可能無法使用不同的狀態代碼。
在我看來,如果您對中間狀態代碼不感興趣,則可以安全地假定最終狀態代碼在2xx(成功)范圍內,否則,調用將不會成功。
不幸的是,狀態代碼沒有出現在ResponseHeaders
詞典中。
Erik的答案無法在Windows Phone上正常運行。 執行以下操作:
class WebClientEx : WebClient
{
private WebResponse m_Resp = null;
protected override WebResponse GetWebResponse(WebRequest Req, IAsyncResult ar)
{
try
{
this.m_Resp = base.GetWebResponse(request);
}
catch (WebException ex)
{
if (this.m_Resp == null)
this.m_Resp = ex.Response;
}
return this.m_Resp;
}
public HttpStatusCode StatusCode
{
get
{
if (m_Resp != null && m_Resp is HttpWebResponse)
return (m_Resp as HttpWebResponse).StatusCode;
else
return HttpStatusCode.OK;
}
}
}
至少在使用OpenReadAsync
; 對於其他xxxAsync
方法,強烈建議仔細測試。 該框架在代碼路徑中的某個位置調用GetWebResponse。 所有需要做的就是捕獲並緩存響應對象。
此代碼段中的后備代碼為200,因為無論如何,真實的HTTP錯誤(500、404等)都被報告為異常。 此技巧的目的是捕獲非錯誤代碼,在我的特定情況下為304(未修改)。 因此,回退假定狀態代碼某種程度上不可用,至少是非錯誤的。
你應該用
if (e.Status == WebExceptionStatus.ProtocolError)
{
HttpWebResponse response = (HttpWebResponse)ex.Response;
if (response.StatusCode == HttpStatusCode.NotFound)
System.Diagnostics.Debug.WriteLine("Not found!");
}
這就是我用來擴展WebClient功能的方法。 StatusCode和StatusDescription將始終包含最新的響應代碼/描述。
/// <summary>
/// An expanded web client that allows certificate auth and
/// the retrieval of status' for successful requests
/// </summary>
public class WebClientCert : WebClient
{
private X509Certificate2 _cert;
public WebClientCert(X509Certificate2 cert) : base() { _cert = cert; }
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
if (_cert != null) { request.ClientCertificates.Add(_cert); }
return request;
}
protected override WebResponse GetWebResponse(WebRequest request)
{
WebResponse response = null;
response = base.GetWebResponse(request);
HttpWebResponse baseResponse = response as HttpWebResponse;
StatusCode = baseResponse.StatusCode;
StatusDescription = baseResponse.StatusDescription;
return response;
}
/// <summary>
/// The most recent response statusCode
/// </summary>
public HttpStatusCode StatusCode { get; set; }
/// <summary>
/// The most recent response statusDescription
/// </summary>
public string StatusDescription { get; set; }
}
因此,您可以發表文章並通過以下方式獲得結果:
byte[] response = null;
using (WebClientCert client = new WebClientCert())
{
response = client.UploadValues(postUri, PostFields);
HttpStatusCode code = client.StatusCode;
string description = client.StatusDescription;
//Use this information
}
以防萬一其他人需要上述黑客的F#版本。
open System
open System.IO
open System.Net
type WebClientEx() =
inherit WebClient ()
[<DefaultValue>] val mutable m_Resp : WebResponse
override x.GetWebResponse (req: WebRequest ) =
x.m_Resp <- base.GetWebResponse(req)
(req :?> HttpWebRequest).AllowAutoRedirect <- false;
x.m_Resp
override x.GetWebResponse (req: WebRequest , ar: IAsyncResult ) =
x.m_Resp <- base.GetWebResponse(req, ar)
(req :?> HttpWebRequest).AllowAutoRedirect <- false;
x.m_Resp
member x.StatusCode with get() : HttpStatusCode =
if not (obj.ReferenceEquals (x.m_Resp, null)) && x.m_Resp.GetType() = typeof<HttpWebResponse> then
(x.m_Resp :?> HttpWebResponse).StatusCode
else
HttpStatusCode.OK
let wc = new WebClientEx()
let st = wc.OpenRead("http://www.stackoverflow.com")
let sr = new StreamReader(st)
let res = sr.ReadToEnd()
wc.StatusCode
sr.Close()
st.Close()
您可以嘗試使用此代碼從WebException或OpenReadCompletedEventArgs.Error獲取HTTP狀態代碼。 它也可以在Silverlight中使用,因為SL沒有定義WebExceptionStatus.ProtocolError。
HttpStatusCode GetHttpStatusCode(System.Exception err)
{
if (err is WebException)
{
WebException we = (WebException)err;
if (we.Response is HttpWebResponse)
{
HttpWebResponse response = (HttpWebResponse)we.Response;
return response.StatusCode;
}
}
return 0;
}
您應該可以使用“ client.ResponseHeaders [..]”調用,有關從響應中獲取內容的示例,請參見此鏈接 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.