3

さて、私はこの問題に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エンコーディングの問題を直接示しています。

4

1 に答える 1

0

皆さんは私が狂人だと思うでしょうが、午後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;
    }
}
于 2013-01-17T21:11:52.227 に答える