95 votes

Comment obtenir le code d'état du webclient ?

J'utilise le WebClient pour envoyer des données à un formulaire web. Je voudrais obtenir le code d'état de la réponse à la soumission du formulaire. Jusqu'à présent, j'ai trouvé comment obtenir le code d'état en cas d'exception.

Catch wex As WebException
        If TypeOf wex.Response Is HttpWebResponse Then
          msgbox(DirectCast(wex.Response, HttpWebResponse).StatusCode)
            End If

Cependant, si le formulaire est soumis avec succès et qu'aucune exception n'est levée, je ne connaîtrai pas le code d'état (200, 301, 302,...).

Existe-t-il un moyen d'obtenir le code d'état lorsqu'aucune exception n'est levée ?

PS : je préfère ne pas utiliser httpwebrequest/httpwebresponse

93voto

Henrik Hartz Points 1919

Vous pouvez vérifier si l'erreur est de type WebException et ensuite inspecter le code de réponse ;

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!");
}

ou

try
{
    // send request
}
catch (WebException e)
{
    // check e.Status as above etc..
}

0 votes

Merci beaucoup pour cette réponse qui m'indique la bonne façon d'obtenir les en-têtes de réponse - à partir de WebException, et non de WebClient.ResponseHeaders.

1 votes

Oui, la meilleure approche consiste à lire les données de la réponse dans un bloc try catch et à attraper les WebExceptions.

0 votes

En général, il suffit d'attraper ce type d'exception en premier, puis d'attraper les exceptions plus génériques plus tard. Plutôt que d'utiliser un if(getType). Cela pourrait valoir la peine d'être modifié ?

34voto

Dmitry S. Points 3898

Il existe un moyen de le faire en utilisant la réflexion. Elle fonctionne avec .NET 4.0. Elle accède à un champ privé et peut ne pas fonctionner dans d'autres versions de .NET sans modifications.

Je ne sais pas pourquoi Microsoft n'a pas exposé ce champ avec une propriété.

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;
}

2 votes

Pour information, ceci n'est pas possible sur Windows Phone qui ne permet pas d'accéder aux membres privés, même par réflexion.

0 votes

Notez que BindingFlags nécessite "using System.Reflection ;".

0 votes

Bien, mais y a-t-il un moyen d'obtenir le SubStatusCode ? Par exemple 403.1 ou 403.2 ?

30voto

Erik Philips Points 18156

Si vous utilisez .Net 4.0 (ou moins) :

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;
        }
    }

Si vous utilisez .Net 4.5.X ou une version plus récente, passez à l'option HttpClient :

var response = await client.GetAsync("http://www.contoso.com/");
var statusCode = response.StatusCode;

0 votes

Ne fonctionne pas sur Windows Phone - GetWebResponse() n'existe que dans la version à deux paramètres. Toujours +1.

0 votes

Intéressant que ça ne marche pas. Content que votre réponse fasse l'affaire !

0 votes

Cela a fonctionné pour moi, alors que la réflexion dans les réponses supérieures n'a pas fonctionné (application .NET 4.5 Windows 7 et 10).

24voto

kbrimington Points 14081

Je l'ai essayé. Les ResponseHeaders n'incluent pas le code d'état.

Si je ne me trompe pas, WebClient est capable de faire abstraction de plusieurs requêtes distinctes dans un seul appel de méthode (par exemple, en gérant correctement les réponses 100 Continue, les redirections, etc.) Je soupçonne que sans utiliser HttpWebRequest y HttpWebResponse un code d'état distinct peut ne pas être disponible.

Il me semble que, si vous n'êtes pas intéressé par les codes d'état intermédiaires, vous pouvez supposer sans risque que le code d'état final est de l'ordre de 2xx (succès), sinon, l'appel ne serait pas réussi.

Malheureusement, le code d'état n'est pas présent dans le code d'accès. ResponseHeaders dictionnaire.

2 votes

Il semble que le seul moyen soit le webrequest/response.

1 votes

Cela semble être un problème si vous cherchez explicitement un autre message de la série 200 (par exemple 201 CREATED - voir : w3.org/Protocoles/rfc2616/rfc2616-sec10.html ) :-/ Ce serait bien si cela était explicitement disponible même si les "intermédiaires" ont été ignorés.

1 votes

@NormanH, je ne suis pas en désaccord. Il semblerait que WebClient soit une abstraction un peu fuyante en ce qui concerne les codes d'état. A la vôtre !

3voto

PapyRef Points 493

Vous devez utiliser

if (e.Status == WebExceptionStatus.ProtocolError)
{
   HttpWebResponse response = (HttpWebResponse)ex.Response;             
   if (response.StatusCode == HttpStatusCode.NotFound)
      System.Diagnostics.Debug.WriteLine("Not found!");
}

3 votes

Pourquoi cette question a-t-elle été votée ? L'OP indique clairement : However if the form is submitted successfully and no exception is thrown...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X