好吧,伙计们,我已经为这个问题苦苦挣扎了一天左右,但没有明确的解决方案。我将从例外开始:
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添加到stream writer等。所有的结果都是一样的。
也许整个磨难中最令人沮丧的部分是,我能够立即用 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 编码的问题。