さて、私はこの問題に1日ほど取り組んできましたが、明確な解決策はありませんでした。私は例外から始めます:
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)
ユーザーにログインするためにJIRARESTAPIに接続しようとしています。JIRAシステムは現在4.4.1を実行しており、ヒットしようとしているAPI情報はhttps://developer.atlassian.com/static/rest/jira/4.4.1.htmlに記載されています。(「/ auth / 1 / session」APIのPOSTリクエストを参照してください)
APIは、ユーザー資格情報のJSON本文を使用してPOSTリクエストを呼び出します。JSONを手動でビルドすることと、JSONライブラリを使用することの両方を試しましたが、結果は同じでした。私が送信しているjsonは次のとおりです。
{
"username": "test",
"password": "test"
}
コンテンツタイプとエンコーディングを想像できるものに変更しようとしました。これには、「text / json」、「application / json」、ストリームライターへのEncoding.UTF8の追加などが含まれます。すべての結果は同じです。
おそらく、この試練全体の中で最も苛立たしい部分は、Android用のJavaでこれをすぐに書くことができたということです。したがって、Windows Phone 8やC#ほどAPIの誤解ではないと思います。誤解。
最後に指摘すべき点は次のとおりです。
- GETリクエストを使用するようにコードを変更し、「http://www.google.com」をポイントして、リクエストコールバックを削除すると(応答に直接スキップ)、すべてが機能し、期待どおりの結果が得られます。
- HttpWebRequestの「BeginX」「EndX」メソッドに混乱しています。非同期タスクは理解していますが、C#がこれをどのように管理するかは正確ではありません。ほとんどのMSDNドキュメントはこれらを使用せず、代わりに「GetRequest()」および「GetResponse()」のメソッドを備えています。これらははるかに簡単に見えます。そして、私がふるいにかけた最新の例でも、これらの方法を使用しています。これらのメソッドは、非同期で実行できるすべてのものが確実に実行されるように、Windows Phone8SDKで削除されたと想定しています。
- Windows Phone8エミュレーター以外のブラウザーから直接JIRAURLにアクセスすると、ドキュメントで概説されている有効な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エンコーディングの問題を直接示しています。