2017-02-10 44 views
1

私はC#のを学び始め、そして私はまた、モバイル環境の開発に経験したことがありません。私はJavaでの経験があり、そこからいくつかの知識を取り入れることができます。XamarinとAndroidにC#を使用してWebページのログインフォームにポストを作る

私はVisualStudioを2017RCを持っている、とXamarin.Androidプロジェクトを開始しました。さらに、登録とログイン、およびトークン生成用のASP.NETサイト(SQLiteユーザストレージ)があります。私の目標は、ユーザーが彼/彼女がアクセストークンを取得し、ウェブサイトにログインすることができ、その後、彼/彼女の名前とパスワードを入力することができる場所xamarinでビューを作ることです。

は、私はすでにLoginViewをした、それが今、私はウェブサイトに満たされたデータを掲載してXamarin.AndroidのC#を使用してページにログインする必要が ...ケーキの作品でした。私がどれくらいの距離を持っているか見てみましょう。ライン

HttpResponseMessage responseMessage = await client.PostAsync("/Login?returnurl=%2FGame%2Fkz%2FToken", formContent); 

でまあ

protected override void OnCreate(Bundle bundle) 
{ 
    base.OnCreate(bundle); 

    SetContentView(Resource.Layout.LoginWebview); 

    //code for getting the login details(emial, password) from the user 
    //code for getting the access token 
    //apiBaseUri is fixed value 

    MainAsync(email, password, apiBaseUri, loginToken).Wait(); 
} 


public static async Task MainAsync(string email, string password, string apiBaseUri, string loginToken) 
{ 
    var token = await GetApiTokenAsync(email, password, apiBaseUri, loginToken); 
} 

public static async Task<string> GetApiTokenAsync(string email, string password, string apiBaseUri, string tokenValue) 
{ 
    var token = string.Empty; 

    var handler = new HttpClientHandler() 
    { 
     AllowAutoRedirect = false 
    }; 


    using (var client = new HttpClient(handler)) 
    { 
     client.BaseAddress = new Uri(apiBaseUri); 
     client.DefaultRequestHeaders.Accept.Clear(); 
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
     client.Timeout = TimeSpan.FromSeconds(60); 

     //set cookie 
     client.DefaultRequestHeaders.Add("Set-Cookie", CookieManager.Instance.GetCookie(apiBaseUri)); 

     //setup login data 
     var formContent = new FormUrlEncodedContent(new[] 
     { 
//new KeyValuePair<string, string>("grant_type", "password"), 
new KeyValuePair<string, string>("Email", username), 
new KeyValuePair<string, string>("Password", password), 
new KeyValuePair<string,string>("__RequestVerificationToken",tokenValue), 
new KeyValuePair<string,string>("RememberMe","false") 
      }); 

     //send request    
     HttpResponseMessage responseMessage = await client.PostAsync("/Login?returnurl=%2FGame%2Fkz%2FToken", formContent); 
     var responseJson = await responseMessage.Content.ReadAsStringAsync(); 
     var jObject = JObject.Parse(responseJson); 
     token = jObject.GetValue("access_token").ToString(); 

     return token; 
    } 

} 
} 

プログラムがハングし、私はトークンバックのアクセスを得ませんでした。

ウェブサイトからの問題を見てみましょう:ウェブブラウザでは、次のリンクを使ってログインフォームを開くことができます:(私はそれを秘密にするためにURLにいくつかのダミー値( "ゲーム")を使います) http://www.game.nl/PlayGame/kz/Account/Login?ReturnUrl=%2FGame%2Fkz%2Ftoken

このウェブサイトを開くと、メールとパスワードを入力できます。次にログインボタンをクリックするとアクセストークンが得られます(これは後の目的で使用されます)。私はこのポイントを取得したいのですが、Androidの携帯電話で、C#で、もちろん

は、私は、彼らはまた、解決策に関連していると思うので、ウェブサイトに関するいくつかの追加の情報を一覧表示するつもりです。私はウェブサイトでログインしている場合 詳細は、以下のとおりです。 (私はネットワーク]タブでは、Google Chromeの開発ツールで詳細を確認してください)

一般:

FormData:

  • メール:[email protected]
  • パスワード:chocolate09#
  • __RequestVerificationToken:CfDJ8L1aKkmfKmBLlQIwHTacxWKOtRekEcOfxKQGBrXUEkE2XpWyxYmMKOTlgZ7gCZq3FEx8ILF_VgQcsjBztZhCwUUYSV966s1BgjFs5I8IefGSoei5hfzK-WQQr8Ztjpn3oGq40neXx4_iBUUMRjFpKz_DdBqzQ
  • リメンバー・ミー:偽

フォームデータのソース:

メール=例%の40company。NL &パスワード= chocolate09%23 & __RequestVerificationToken = CfDJ8L1aKkmfKmBLlQIwHTacxWKOtRekEcOfxKQGBrXUEkE2XpWyxYmMKOTlgZ7gCZq3FEx8ILF_VgQcsjBztZhCwUUYSV966s1BgjFs5I8IefGSoei5hfzK-WQQr8Ztjpn3oGq40neXx4_iBUUMRjFpKz_DdBqzQ &リメンバー・ミー= falseを

だから私は、この時点で立ち往生しています、そしてそれは

await client.PostAsync("/Login?returnurl=%2FGame%2Fkz%2FToken", formContent); 

でハングなぜ私は知らない最後の行のVSコンソール出力:

02-11 00:07:01.404 D/Mono (2853): [0x982bf930] hill climbing, change max number of threads 2 
02-11 00:07:07.829 D/Mono (2853): [0x9847f930] worker finishing 
Thread finished: <Thread Pool> #4 
The thread 'Unknown' (0x4) has exited with code 0 (0x0). 

MainAsync(email, password, apiBaseUri, loginToken).Wait();

具体的.Wait()声明:私は信じている

答えて

2

あなたの問題はOnCreateで、このラインです。 OnCreateは常にUIスレッドで呼び出されます。 async/awaitを使用して、.Wait()または.Resultを使用して結果を待つと、継続がUIスレッドに戻ることができないため、アプリケーションがハングアップし、PostAsyncの呼び出しでこれが最初の呼び出しであることがわかりますそれは実際に実行するために別のスレッドを使用します。

.Wait()を呼び出す理由は、OnCreateが非同期メソッドではないためです。うれしいことに、それは可能です。私は(あなたが非同期として、ボイドのメソッドをマークすることができ、そうすることで落とし穴があるので、メソッド内のすべての例外をキャッチしてください!)asyncawaitようになりましたI

// Mark the method as async 
protected override async void OnCreate(Bundle bundle) 
{ 
    base.OnCreate(bundle); 

    SetContentView(Resource.Layout.LoginWebview); 

    // remove the .Wait() and await the method call 
    await MainAsync(email, password, apiBaseUri, loginToken); 
} 
+0

おかげで多くのことを、ログインし、それをマークします続けることができます...しかし、残念ながら私は404のエラーが見つかりませんでした 'responseJson'、私のために奇妙な...それについてあなたの意見は? – mirind4

関連する問題