System.Net.WebException when sending JSON using POST request to a Jira API
Alright guys, I have been wrestling with this issue for a day or so with no clear resolution. I will start with the exception:
The remote server returned an error: NotFound.
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
I am attempting to connect to the JIRA rest API for logging in a user. Our JIRA system is currently running 4.4.1, and the API information I am attempting to hit is documented here: https://developer.atlassian.com/static/rest/jira/4.4.1.html. (See the POST request for the "/auth/1/session" API)
The API calls for a POST request, with a JSON body for the user credentials. I have tried both building the JSON manually, as well as using a JSON library, and the results were the same. The json I am sending is:
{
"username": "test",
"password": "test"
}
I have attempted to change the content type and encoding to anything I can imagine. This includes "text/json", "application/json", adding Encoding.UTF8 to the stream writer, etc. All the results are the same.
Perhaps the most frustrating part of this entire ordeal, is that I was able to write this in Java for Android in no time at all, so I do not believe it is an API misunderstanding as so much as a Windows Phone 8 and/or C# misunderstanding.
A few final things to point out:
Below is the code as I currently have it. I have taken out my Jira host name
class LoginService
{
public static UserSession login(string aUsername, string aPassword)
{
String loginUrl = "http://{myjiraurl}/rest/auth/1/session/";
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(loginUrl);
string jsonBody = JsonHelper.GenerateLoginJson(aUsername, aPassword);
RequestInformation requestInfo = new RequestInformation();
requestInfo.request = request;
requestInfo.JsonBody = jsonBody;
requestInfo.request.Method = "POST";
requestInfo.request.ContentType = "text/json";
requestInfo.request.ContentLength = (long)jsonBody.Length;
request.BeginGetRequestStream(new AsyncCallback(LoginRequestCallback), requestInfo);
return null;
}
private static void LoginRequestCallback(IAsyncResult result)
{
RequestInformation requestInfo = (RequestInformation)result.AsyncState;
HttpWebRequest webRequest = requestInfo.request;
// End the Asynchronus request.
Stream requestSream = webRequest.EndGetRequestStream(result);
StreamWriter requestWriter = new StreamWriter(requestSream);
requestWriter.Write(requestInfo.JsonBody);
requestWriter.Flush();
requestWriter.Close();
requestSream.Close();
webRequest.BeginGetResponse(new AsyncCallback(LoginResponseCallback), requestInfo);
}
private static void LoginResponseCallback(IAsyncResult result)
{
RequestInformation requestInfo = (RequestInformation)result.AsyncState;
HttpWebRequest webRequest = requestInfo.request;
try
{
HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(result);
if (response.StatusCode == HttpStatusCode.OK)
{
Stream streamResponse = response.GetResponseStream();
string responseResult = StreamHelper.ReadStreamToString(streamResponse);
streamResponse.Close();
}
response.Close();
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
System.Diagnostics.Debug.WriteLine(e.StackTrace);
}
}
}
public class RequestInformation
{
// This class stores the request state of the request and any necessary information for the request body
public HttpWebRequest request;
public string JsonBody { get; set; }
public string Result { get; set; }
public RequestInformation()
{
request = null;
}
}
Edit: For some clarification, the code is failing when attempting to generate the response object on this line...
HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(result);
Update 1:
I have discovered that I can cast the response of the WebException
into an HttpWebResponse
. This allowed me to see what the exact status code was, which was HttpStatusCode.UnsupportedMediaType
or 415. This now points directly at an issue with the JSON encoding that is being sent to the server.
You guys are going to think I am a lunatic, but as of about 3:00pm I have been getting the expected results.
I will be editing this answer with the updated code once I refactor it a little bit.
Updated working code:
public static async Task<HttpWebResponse> SendHttpPostRequest(string url, string content, string contentType, string acceptType)
{
HttpWebRequest request = HttpWebRequest.CreateHttp(new Uri(url, UriKind.Absolute));
HttpWebResponse response = new HttpWebResponse();
string responseText = "";
request.Method = "POST";
request.ContentType = contentType;
request.Accept = acceptType;
Task<Stream> requestTask = Task.Factory.FromAsync(request.BeginGetRequestStream, asyncResult => request.EndGetRequestStream(asyncResult), (object)null);
await requestTask.ContinueWith(t =>
{
using (Stream stream = requestTask.Result)
using (StreamWriter requestWriter = new StreamWriter(stream))
{
requestWriter.Write(content);
}
});
Task<WebResponse> responseTask = Task.Factory.FromAsync(request.BeginGetResponse, asyncResult => request.EndGetResponse(asyncResult), (object)null);
await responseTask.ContinueWith(t =>
{
try
{
response = (HttpWebResponse)responseTask.Result;
}
catch (AggregateException ae)
{
foreach (Exception e in ae.InnerExceptions)
{
if (e is WebException)
{
response = (HttpWebResponse)((WebException)e).Response;
System.Diagnostics.Debug.WriteLine(e.Message);
System.Diagnostics.Debug.WriteLine(e.StackTrace);
}
}
}
});
return response;
}
}
链接地址: http://www.djcxy.com/p/45882.html
上一篇: 从C#代码调用REST服务