[英]Make a post to a login form of a webpage using C# in Xamarin and Android
我刚刚开始学习C#,并且从未在开发移动环境方面经历过。 我有Java方面的经验,可以从那里学到一些知识。
我拥有VisualStudio 2017RC,并启动了Xamarin.Android项目。 此外,还有一个用于注册和登录以及令牌生成(SQLite用户存储)的ASP.NET网站。 我的目标是在xamarin中进行查看,用户可以在其中键入他/她的名称和密码,然后可以登录到他/她获得访问令牌的网站。
我已经制作了一个LoginView,这真是小菜一碟……现在,我必须将填充的数据发布到网站上,并使用Xamarin.Android中的c#登录到页面。 让我们看看我走了多远。
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;
}
}
}
好吧
HttpResponseMessage responseMessage = await client.PostAsync("/Login?returnurl=%2FGame%2Fkz%2FToken", formContent);
该程序挂起,我没有访问令牌。
让我们从网站的角度看问题:在网络浏览器中,可以使用以下链接打开登录表单:(我将在URL中使用一些虚拟值(“游戏”)以保持其私密性) http:/ /www.game.nl/PlayGame/kz/Account/Login?ReturnUrl=%2FGame%2Fkz%2Ftoken
打开这个网站,我可以输入电子邮件和密码。 然后,如果我单击登录按钮,我将获得一个访问令牌(将用于以后的目的)。 我想说到这一点,但是当然可以在带有Android手机的C#中使用
我将列出有关该网站的其他信息,因为我认为它们也与解决方案有关。 如果我通过网站登录,详细信息如下。 (我在网络标签上使用Google Chrome开发者工具检查了详细信息)
一般:
FORMDATA:
表单数据的来源:
电子邮件=示例%40company.nl&密码= chocolate09%23&__ RequestVerificationToken = CfDJ8L1aKkmfKmBLlQIwHTacxWKOtRekEcOfxKQGBrXUEkE2XpWyxYmMKOTlgZ7gCZq3FEx8ILF_VgQcsjBztZhCwUUYSV966s1BgjFs5I8IefGSoei5hfzK-WQQr8Ztjpn3oGq40neXx4_iBUUMRjFpKz_DdBqzQ&了rememberMe =假
所以我被困在这一点上,我不知道为什么它挂在
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).
我相信您的问题是OnCreate
这一行:
MainAsync(email, password, apiBaseUri, loginToken).Wait();
特别是.Wait()
语句。 总是在UI线程上调用OnCreate
。 每当您使用async / await并使用.Wait()
或.Result
.Wait()
结果时,就会发生不好的事情,并且由于继续操作无法跳回到UI线程,您的应用程序将挂起-您将在对PostAsync
的调用中PostAsync
此内容是第一个实际上将使用其他线程运行的调用。
我猜你之所以调用.Wait()
的原因是因为OnCreate
不是异步方法-好消息是它可以。 我会将其标记为async
并await
登录(您可以将无效方法标记为异步,这样做有很多陷阱,因此请确保在方法内部捕获所有异常!)
// 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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.