1

I have the following code which is connecting to an api with basic authentication:

var worker = new BackgroundWorker();

worker.DoWork += (sender, args) => {
    var request = HttpWebRequest.Create(url);
    request.Credentials = new NetworkCredential(email, password);
    args.Result = request.GetResponse();
};

worker.RunWorkerCompleted += (sender, e) => {
    String msg = "";
    // need to check whether there has been an error 
    // otherwise trying to get the result throws an exception
    if (e.Error == null) {
        var code = ((HttpWebResponse)e.Result).StatusCode;
        if (code == HttpStatusCode.OK)
            msg = "Connectivity OK";
        else if (code == HttpStatusCode.Unauthorized)
            msg = "Wrong username";
        else if (code == HttpStatusCode.Forbidden)
            msg = "Wrong password";
        else if (code == HttpStatusCode.NotFound)
            msg = "Wrong organisation";
        else
            msg = "Connectivity Error: " + code;
    } else {
        msg = "Connectivity error: " + e.Error.Message;
    }
    label.Text = msg;
    log.d(msg);
};

I would like to get the status code to be able to tell the user if the username, password or organisation is wrong. Unfortunately, if there is a network error, trying to get e.Result causes another error so I can only check the status code if there hasn't been an error.

I've tried using various other supposedly asyncronous C# network methods, e.g. webclient.downloadStringAsync but they are not truly asynchronous; the DNS resolution is done on the current thread. I also can't use async and await because I have to use Net Framework 4.0.

leppie
  • 115,091
  • 17
  • 196
  • 297
eggbert
  • 3,105
  • 5
  • 30
  • 39

1 Answers1

0

Just found the answer to my own question, here: https://stackoverflow.com/a/4700154/519074

Server responses in the range of 4xx and 5xx throw a WebException, so you have to check for that. This code works:

var worker = new BackgroundWorker();

worker.DoWork += (sender, args) => {
    var request = HttpWebRequest.Create(url);
    request.Credentials = new NetworkCredential(email, password);
    // TODO: set proxy settings if necessary
    try {
        args.Result = ((HttpWebResponse)request.GetResponse()).StatusCode;
    } catch (WebException we) {
        args.Result = ((HttpWebResponse)we.Response).StatusCode;
    }
};

worker.RunWorkerCompleted += (sender, e) => {
    String msg = "";
    var code = (HttpStatusCode)e.Result;
    if (code == HttpStatusCode.OK)
        msg = "Connectivity OK";
    else if (code == HttpStatusCode.Forbidden)
        msg = "Wrong username or password";
    else if (code == HttpStatusCode.NotFound)
        msg = "Wrong organisation";
    else
        msg = "Connectivity Error: " + code;
    label.Text = msg;
    log.d(msg);
};
Community
  • 1
  • 1
eggbert
  • 3,105
  • 5
  • 30
  • 39