简体   繁体   中英

C# Closing an issue in Jira using the REST API

I know this question has been asked before, but I cannot seem to get it too work.

I'm able to authenticate to Jira and create a new ticket using a JSON string, but attempting to close the same issue produces a "400 Bad Request" error.

Code:

public string jiraJSON;
public void openJira()
{
    jiraJSON = string.Format(@"{{""fields"":{{""assignee"":{{""name"":""{0}""}},""project"":{{""key"":""TS""}},""summary"":""{1}"",""description"":""{2}"",""issuetype"":{{""name"":""Unplanned Event""}} }} }}", jiraUsernameTextBox.Text, jiraSummary, jiraDescription);
    Dictionary<string, string> jiraResponse = sendHTTPtoJIRA(jiraJSON,"open","");
}
public void closeJira(string jiraKey)
{
    jiraJSON = @"{{""update"":{{""comment"":[{{""add"":{{""body"":""Done""}}}}]}},""fields"":{{""resolution"":{{""name"":""Done""}}}},""transition"":{{""id"":""51""}}}}";
    jiraResponse = sendHTTPtoJIRA(jiraJSON,"close",jiraKey);    
}
private Dictionary<string,string> sendHTTPtoJIRA(string json, string operation,string issueID)
        {
            string restURL="";
            string method = "";
            switch (operation)
            {
                case "open":
                    restURL = string.Format("{0}rest/api/2/issue/", jiraURL);
                    method = "POST";
                    break;
                case "close":
                    restURL = string.Format("{0}rest/api/2/issue/{1}/transitions/?expand=transitions.fields", jiraURL,issueID);
                    method = "POST";                    
                    break;
            }

            HttpWebResponse response = null;
            HttpWebRequest request = WebRequest.Create(restURL) as HttpWebRequest;
            request.Method = method;
            request.Accept = "application/json";
            request.ContentType = "application/json";
            request.Headers.Add("Authorization", "Basic " + authenticateJira());
            byte[] data = Encoding.UTF8.GetBytes(json);
            using (var requestStream = request.GetRequestStream())
            {
                requestStream.Write(data, 0, data.Length);
                requestStream.Close();
            }
            using (response = request.GetResponse() as HttpWebResponse)
            {
                var reader = new StreamReader(response.GetResponseStream());
                string str = reader.ReadToEnd();
                displayMessages(string.Format("The server returned '{0}'\n{1}", response.StatusCode, str), "white", "purple");
                var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
                var sData = jss.Deserialize<Dictionary<string, string>>(str);
                sData.Add("code", response.StatusCode.ToString());
                request.Abort();
                return sData;
            }
        }

I've paraphrased the code a little bit for the sake of clarity but the "sendHTTPtoJIRA" method is verbatim and the jiraJSON strings are also verbatim.

Using this code, I'm able to open a Issue and assign it to myself, however when I attempt to close the issue, I get a "400 Bad Request" which tells me that my jiraJSON string in the "closeJira" method isn't correct.

The exception lands on the line "using (response = request.GetResponse() as HttpWebResponse)" and references "jiraResponse = sendHTTPtoJIRA(jiraJSON,"close",jiraKey);" as the line that called the method, so I know it's faulting when it attempts to close the issue.

Common issues from other posts that I've addressed:

  1. The user account that I'm using has permissions to close issues.
  2. I've tried both "POST" and "PUT" methods. Using "PUT" produces a "405 Method not allowed" error.
  3. Escaped the curly braces and quotes.

Expanded JSON string I'm using to close the issue:

{{
        ""update"":{{""comment"":[{{""add"":{{""body"":""Done""}}}}]}},
        ""fields"":{{""resolution"":{{""name"":""Done""}}}},
        ""transition"":{{""id"":""51""}}
}}

I've tried variations, of course. Nothing seems to work. I've also included the 51 with and without quotes to no avail.

When I browse to http://jira/rest/api/2/issue/TS-1000/transitions/?expand=transitions.fields I get the following output (which is how I got "51" for the ID in my jiraJSON string):

{
    "expand": "transitions",
    "transitions": [{
            "id": "11",
            "name": "Start Progress",
            "to": {
                "self": "http://jira/rest/api/2/status/3",
                "description": "This issue is being actively worked on at the moment by the assignee.",
                "iconUrl": "http://jira/images/icons/statuses/inprogress.png",
                "name": "In Progress",
                "id": "3",
                "statusCategory": {
                    "self": "http://jira/rest/api/2/statuscategory/4",
                    "id": 4,
                    "key": "indeterminate",
                    "colorName": "yellow",
                    "name": "In Progress"
                }
            },
            "fields": {
                "attachment": {
                    "required": false,
                    "schema": {
                        "type": "array",
                        "items": "attachment",
                        "system": "attachment"
                    },
                    "name": "Attachment",
                    "operations": []
                },
                "assignee": {
                    "required": true,
                    "schema": {
                        "type": "user",
                        "system": "assignee"
                    },
                    "name": "Assignee",
                    "autoCompleteUrl": "http://jira/rest/api/latest/user/assignable/search?issueKey=TS-2034&username=",
                    "operations": ["set"]
                }
            }
        }, {
            "id": "51",
            "name": "Close Issue",
            "to": {
                "self": "http://jira/rest/api/2/status/6",
                "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.",
                "iconUrl": "http://jira/images/icons/statuses/closed.png",
                "name": "Closed",
                "id": "6",
                "statusCategory": {
                    "self": "http://jira/rest/api/2/statuscategory/3",
                    "id": 3,
                    "key": "done",
                    "colorName": "green",
                    "name": "Done"
                }
            },
            "fields": {
                "resolution": {
                    "required": true,
                    "schema": {
                        "type": "resolution",
                        "system": "resolution"
                    },
                    "name": "Resolution",
                    "operations": ["set"],
                    "allowedValues": [{
                            "self": "http://jira/rest/api/2/resolution/1",
                            "name": "Fixed",
                            "id": "1"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/5",
                            "name": "Cannot Reproduce",
                            "id": "5"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/3",
                            "name": "Duplicate",
                            "id": "3"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/4",
                            "name": "Incomplete",
                            "id": "4"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/7",
                            "name": "Review Completed",
                            "id": "7"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/6",
                            "name": "Unresolved",
                            "id": "6"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/2",
                            "name": "Won't Fix",
                            "id": "2"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/10000",
                            "name": "Done",
                            "id": "10000"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/10100",
                            "name": "Edgewater Review",
                            "id": "10100"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/10200",
                            "name": "Active Project",
                            "id": "10200"
                        }, {
                            "self": "http://jira/rest/api/2/resolution/10300",
                            "name": "Won't Do",
                            "id": "10300"
                        }
                    ]
                },
                "customfield_10652": {
                    "required": false,
                    "schema": {
                        "type": "string",
                        "custom": "com.atlassian.jira.plugin.system.customfieldtypes:textarea",
                        "customId": 10652
                    },
                    "name": "Resolution Activity",
                    "operations": ["set"]
                }
            }
        }
    ]
}

So what am I doing with my JSON string? Any suggestions would be appreciated. Thanks!

The formatting JSON string with double quotes always goes wrong. So use Json.Net dll and use JObject to form json string.

The below is sample to update custom field value `

JObject customFiledObject = new JObject( new JProperty("fields", new JObject(new JProperty("customfield_1100", new JArray(10)))));

After preparing desired JSON object , format object to Json string like below

string jSonString = customFiledObject.ToString(Newtonsoft.Json.Formatting.Indented);

I know the question has been answered for some time now but for anyone else suffering from Jiras '400 Bad Request', you can capture a more meaningful error by adding the catch statement below.

catch (System.Net.WebException ex)
{
    WebResponse resp = ex.Response;
    string JiraErrorMessages = (new System.IO.StreamReader(resp.GetResponseStream(), true)).ReadToEnd();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM