Я использую WebClient
класс для публикации некоторых данных в веб-форме. Я хочу получить код статуса ответа при отправке формы. Пока что узнал, как получить код статуса, если есть исключение
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;
источник
Ответ Эрика не работает на 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!"); }
источник
However if the form is submitted successfully and no exception is thrown...
Это то, что я использую для расширения функциональности 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()
источник
У вас должна быть возможность использовать вызов client.ResponseHeaders [..], см. Эту ссылку , чтобы увидеть примеры получения данных из ответа.
источник
Вы можете попробовать этот код, чтобы получить код состояния HTTP из WebException или из OpenReadCompletedEventArgs.Error. Это работает и в 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; }
источник