3

The Problem

I am trying to create a REST API call using a HttpWebRequest to our in-house Jira server. But somehow I keep getting back a (400) Bad Request error. I have also tried with WebClient and other ways but I just don't seem to find the correct approach. Any suggestions?

URL is correct

User is correct

Password is correct

JSON Data also correct

There must be another way of accessing the remote server right? I have been searching but not seem to find a solution.

My Code

public static void CreateJiraRequest(JiraApiObject.RootObject jiraApiObject)
{
    string url = "https://jira-test.ch.*********.net/rest/api/latest/issue/";
    string user = "peno.ch";
    string password = "**********";

    var request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/json";
    request.Credentials = new System.Net.NetworkCredential(user, password);

    string data = JsonConvert.SerializeObject(jiraApiObject);

    using (var webStream = request.GetRequestStream())
    using (var requestWriter = new StreamWriter(webStream, System.Text.Encoding.ASCII))
    {
        requestWriter.Write(data);
    }

    try
    {
        var webResponse = request.GetResponse();
        using (var responseReader = new StreamReader(webResponse.GetResponseStream()))
        {
            string response = responseReader.ReadToEnd();
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

JSON

{
    "fields": {
       "project":
       {
          "key": "FOO"
       },
       "summary": "Test the REST API",
       "issuetype": {
          "name": "Task"
       }
   }
}

Exception

The exception occurs when entering the try block on request.GetResponse();

Additional information: The remote server returned an error: (400) Bad Request.

Visit the Jira Wiki here

Mrs KOODA
  • 149
  • 2
  • 13
  • 1
    Read the error response, it's bound to contain more details. Your assumption of the JSON being correct is probably incorrect. For example your user doesn't have permissions, your data is missing a required field, or something like that. Without any relevant data or error we can't say anything about this. – CodeCaster Feb 06 '19 at 09:58
  • listen keyboard warrior the in the Try block the function throws an exception the only error thrown there is: The remote server returned an error: (400) Bad Request. without any further Information. I have also compared my generated JSON with the one listed on the wiki page they match 1:1 – Mrs KOODA Feb 06 '19 at 10:01
  • Look buddy you're using the ancient HttpWebRequest which is a horrific HTTP API to use. See for example [.Net HttpWebRequest.GetResponse() raises exception when http status code 400 (bad request) is returned](https://stackoverflow.com/questions/692342/net-httpwebrequest-getresponse-raises-exception-when-http-status-code-400-ba) to obtain the response body which should contain more information (as explained [in the docs](https://docs.atlassian.com/software/jira/docs/api/REST/7.12.0/#api/2/issue-createIssue)). Or switch to HttpClient altogether. – CodeCaster Feb 06 '19 at 10:04
  • And sure, your JSON may match an example JSON, but your particular JIRA installation may be configured to require more fields than are present in that example, or other rules that that JSON doesn't adhere to. – CodeCaster Feb 06 '19 at 10:07
  • I have checked with our Jira Administrator. According to him, my JSON is correct. I could add more fields but they would not be required. I'll edit the post and add my current JSON. – Mrs KOODA Feb 06 '19 at 12:32
  • 1
    There's no use guessing based on the input; the output contains the details necessary to solve this. Your input may be syntactically correct, but the server may require more fields to be set or disallows your user to create issues of the given type in the given project. Obtain the response body and read it to discover why you get a 400 response. – CodeCaster Feb 06 '19 at 14:08
  • 1
    Try examining the innerException, I've found that a useful message is usually buried somewhere deep in the stack – so cal cheesehead Feb 06 '19 at 17:54
  • @socalcheesehead Yes i have tried that but the inner exception was null – Mrs KOODA Feb 07 '19 at 07:40

2 Answers2

4

#Solution#

The problem in the code above is that Jira requires encoded credentials. Without encoding the credentials the Jira server will return a 400 Bad Request error with no specific information.

I have written two new functions one for the API request and one for the Encoding of the credentials.

#API Call#

public static string PostJsonRequest(string endpoint, string userid, string password, string json)
    {
        // Create string to hold JSON response
        string jsonResponse = string.Empty;
        
        using (var client = new WebClient())
        {
            try
            {
                client.Encoding = System.Text.Encoding.UTF8;
                client.Headers.Set("Authorization", "Basic " + GetEncodedCredentials(userid, password));
                client.Headers.Add("Content-Type: application/json");
                client.Headers.Add("Accept", "application/json");
                var uri = new Uri(endpoint);
                var response = client.UploadString(uri, "POST", json);
                jsonResponse = response;
            }
            catch (WebException ex)
            {
                // Http Error
                if (ex.Status == WebExceptionStatus.ProtocolError)
                {
                    HttpWebResponse wrsp = (HttpWebResponse)ex.Response;
                    var statusCode = (int)wrsp.StatusCode;
                    var msg = wrsp.StatusDescription;
                    throw new HttpException(statusCode, msg);
                }
                else
                {
                    throw new HttpException(500, ex.Message);
                }
            }
        }

        return jsonResponse;
    }

#Encoding Function#

private static string GetEncodedCredentials(string userid, string password)
{
    string mergedCredentials = string.Format("{0}:{1}", userid, password);
    byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials);
    return Convert.ToBase64String(byteCredentials);
}

Additional Notes: Jira API is case sensitive so for "POST" If you do Fields, Summary, Project it won't work it has to be fields, summary, project

singhswat
  • 832
  • 7
  • 20
Mrs KOODA
  • 149
  • 2
  • 13
0

I had a very similar problem by creating an issue with a webhook in Jira. The problem was that I was not able to tell why I am getting a "Bad request" from Jira while the request looked OK. The solution was to enbale the logging on the right level.

In order to debug the request it was necessary to go

System -> Logging and Profiling -> HTTP Access logging [Enable] and HTTP dump log [Enable].

In addition

Configure logging level for another packages -> and insert org.apache.http with DEBUG level and if you are using a webhook also add com.atlassian.webhooks with DEBUG level.

Then it is very handy to install the "LASTLOG-ADD-ON" which is then available in the

Manage apps

and you can view and search the logs. The error message, which showed me why my issue creating request failed, was in "atlassian-jira-http-dump.log". Hope that this setup will help in debugging.

r0bag
  • 1