System.Net.WebException在使用POST请求向Jira API发送JSON时

好吧,我一直在解决这个问题一天左右,没有明确的解决方案。 我将从例外开始:

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)

我正在尝试连接到JIRA rest API以登录用户。 我们的JIRA系统目前正在运行4.4.1,我试图打的API信息记录在这里:https://developer.atlassian.com/static/rest/jira/4.4.1.html。 (请参阅“/ auth / 1 / session”API的POST请求)

API调用POST请求,并为用户凭证提供JSON主体。 我已经尝试了手动构建JSON以及使用JSON库,结果是相同的。 我发送的json是:

{ 
    "username": "test",
    "password": "test"
}

我试图将内容类型和编码更改为我能想象的任何内容。 这包括“text / json”,“application / json”,将Encoding.UTF8添加到流编写器等。所有结果都是相同的。

也许这整个考验中最令人沮丧的部分是,我能够立即在Java中为Android写这篇文章,所以我不认为这是API的误解,就像Windows Phone 8和/或C#误解。

最后要指出的一些事情是:

  • 如果我将代码更改为使用GET请求,请指向“http://www.google.com”,然后删除请求回调(直接跳过响应),一切正常,我得到我期望的结果。
  • 我对HttpWebRequest的“BeginX”“EndX”方法感到困惑。 我理解异步任务,但不完全如何C#管理这个。 大多数MSDN文档不使用这些,而是​​有“GetRequest()”和“GetResponse()”方法,这看起来更直截了当。 我筛选出来的最近的例子也使用这些方法。 我假设在Windows Phone 8 SDK中删除了这些方法,以确保可以异步运行的所有内容。
  • 如果我从除Windows Phone 8仿真器以外的任何浏览器直接访问JIRA URL,则按文档所述获得有效的403。 但是,如果我直接在模拟器中打开URL,它会提示我输入登录凭据。 这让我觉得基本认证是必需的,所以我尝试了添加,但是我得到了相同的结果。
  • 以下是我目前拥有的代码。 我已经取出了我的Jira主机名

    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;
        }
    }
    

    编辑:对于一些澄清,试图在这一行上生成响应对象时代码失败...

    HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(result);
    

    更新1:

    我发现我可以将WebException的响应转换为HttpWebResponse 。 这使我可以看到确切的状态码是什么,它是HttpStatusCode.UnsupportedMediaType或415.这现在直接指出了发送到服务器的JSON编码的问题。


    你们会认为我是疯子,但是直到下午3点左右,我已经得到了预期的结果。

    一旦我重构了一点,我将用更新的代码编辑这个答案。

    更新的工作代码:

    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/45881.html

    上一篇: System.Net.WebException when sending JSON using POST request to a Jira API

    下一篇: Post JSON over HTTPS