Question

I've been coding a Minecraft session library. Basically, it has methods such as Authenticate() and Refresh() to get access tokens for launchers to use (source). One of the methods, PostHTTP(), takes 2 parameters and outs one (JObject JSON, string endpoint, out int statuscode [for debug reasons]). The proper method name is:

public static string PostHTTP(JObject JSON, string endpoint, out int statusCode)

Now, when the program, for example, uses Authenticate (the launcher does not use the PostHTTP() method directly, but it is used by other methods such as Authenticate()) and supplies a username and password, the Authenticate() method parses the user/pass combo into a JSON.NET JObject, and sends it along to PostHTTP(), like so:

public static string Authenticate(string username, string password, out int statusCode)
{
    JObject toPost = new JObject(
        new JProperty("agent",
            new JObject(
                new JProperty("name", "Minecraft"),
                new JProperty("version", 1))),
        new JProperty("username", username),
        new JProperty("password", password));
    return PostHTTP(toPost, "authenticate", out statusCode);
}

In the PostHTTP() method, this is the current code:

public static string PostHTTP(JObject JSON, string endpoint, out int statusCode)
{ // endpoint = authenticate, invalidate, etc.
    string response = null;
    try
    {
        var req = (HttpWebRequest)WebRequest.Create(Vars.AuthServer + endpoint);
        req.ContentType = "application/json";
        req.Method = "POST";
        using (var sw = new StreamWriter(req.GetRequestStream()))
        {
            sw.Write(JSON.ToString());
            sw.Flush();
            sw.Close();

            var resp = (HttpWebResponse)req.GetResponse();
            using (var sr = new StreamReader(resp.GetResponseStream()))
            {
                response = sr.ReadToEnd();
            }
            //Console.WriteLine(response);
            statusCode = (int)resp.StatusCode;
        }
    }
    catch (WebException)
    {
        statusCode = 69;
        return null;
    }
    return response;
}

Now, for example the user inputs a wrong username/password combo. The auth server will return:

  • An appropriate, non-200 HTTP status code
  • A JSON-encoded dictionary with this format:

    { "error": "Short description of the error",
    "errorMessage": "Longer description which can be shown to the user",
    "cause": "Cause of the error" // optional
    }

The problem is that the code, as of now, only catches the status code and its message (The remote server returned an error: (403) Forbidden).
How do I catch the JSON dictionary along with the status code?

Was it helpful?

Solution

What you need is WebException.Response property. It will be not null if some response was received with error status code.

P.S. You can remove sw.Flush and sw.Close calls, and move the code after them (from GetResponse to setting statusCode) outside of using (sw). You should also dispose resp.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top