[英]Retrieving JSON content by calling a REST API with C# and HttpClient
I'm having a stab at some mobile development with Xamarin and C#. 我正在使用Xamarin和C#进行一些移动开发。 I'm building a simple login screen for an Android app and I'm using the
HttpClient
to make the actual calls but I'm stuck on some of the details to get it to work. 我正在为一个Android应用程序构建一个简单的登录屏幕,我正在使用
HttpClient
进行实际调用,但我仍然坚持一些细节以使其工作。
I have set up a simple Client
class that represents my API client: 我已经设置了一个代表我的API客户端的简单
Client
类:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace Acme.Api
{
public class Session
{
public string Token;
public int Timeout;
}
public class Client
{
public async Task<string> authenticate( string username, string password )
{
using (var client = new HttpClient ())
{
string content = null;
client.BaseAddress = new Uri ("https://example.com/api/");
client.DefaultRequestHeaders.Accept.Clear ();
client.DefaultRequestHeaders.Accept.Add (new MediaTypeWithQualityHeaderValue ("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("Basic", string.Format ("{0}:{1}", username, password));
HttpResponseMessage response = await client.PostAsync ("auth", null);
content = await response.Content.ReadAsStringAsync();
return content;
}
}
}
}
As you can see, the authenticate
method uses a POST
to create a new session on the server. 如您所见,
authenticate
方法使用POST
在服务器上创建新会话。 The /auth
endpoint returns a JSON blob with a token and a timeout value. /auth
端点返回带有令牌和超时值的JSON blob。
This is how the authenticate
method is called: 这是
authenticate
方法的调用方式:
Client myClient = new Client();
Task<string> contentTask = myClient.authenticate( username, password );
var content = contentTask.ToString();
Console.Out.WriteLine(content);
My content
never outputs anything. 我的
content
从不输出任何content
I'm obviously (and without a doubt) doing various things wrong. 我显然(毫无疑问)做了各种错误的事情。
How can I have my authenticate
method return the JSON string I expect? 如何让我的
authenticate
方法返回我期望的JSON字符串?
I have been using these sources for inspiration: 我一直在使用这些来源获取灵感:
http://developer.xamarin.com/guides/cross-platform/advanced/async_support_overview/ http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client http://developer.xamarin.com/guides/cross-platform/advanced/async_support_overview/ http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-网络客户端
Since you are returning a Task
and not just a string
you need to wait upon the myclient.authenticate
method. 由于您要返回一个
Task
而不仅仅是一个string
您需要等待myclient.authenticate
方法。
You wouldnt have to wait if you retruned a string
. 如果你重新编写一个
string
你就不必等待。 Which I think is possible in your case, by just changing the return type from Task<string>
to string
. 我认为在您的情况下,只需将返回类型从
Task<string>
更改为string
。
your Clent authenticate
method : 你的Clent
authenticate
方法:
public class Client
{
public async Task<string> authenticate( string username, string password )
{
using (var client = new HttpClient ())
{
string content = null;
client.BaseAddress = new Uri ("https://example.com/api/");
client.DefaultRequestHeaders.Accept.Clear ();
client.DefaultRequestHeaders.Accept.Add (new MediaTypeWithQualityHeaderValue ("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("Basic", string.Format ("{0}:{1}", username, password));
HttpResponseMessage response = await client.PostAsync ("auth", null);
//deserialize json, not sure if you need it as its not an object that you are returning
jsonstring = await response.Content.ReadAsStringAsync();
var content = JsonConvert.DeserializeObject<string>(jsonstring);
return content;
}
}
}
Consume the Client as : 将客户消费为:
async void btn_click(string username,string password)
{
// This should be an async method as well
Client myClient = new Client();
// added await
string content = await myClient.authenticate(username, password);
Console.Out.WriteLine(content);
}
The sample code is already present in the source of inspiration 示例代码已经存在于灵感源中
GetButton.Click += async (sender, e) => {
Task<int> sizeTask = DownloadHomepage();
ResultTextView.Text = "loading...";
ResultEditText.Text = "loading...\n";
// await! control returns to the caller
// "See await"
var intResult = await sizeTask
// when the Task<int> returns, the value is available and we can display on the UI
ResultTextView.Text = "Length: " + intResult ;
// "returns" void, since it's an event handler
};
public async Task<int> DownloadHomepage()
{
var httpClient = new HttpClient(); // Xamarin supports HttpClient!
Task<string> contentsTask = httpClient.GetStringAsync("http://xamarin.com"); // async method!
// await! control returns to the caller and the task continues to run on another thread
// "See await"
string contents = await contentsTask;
ResultEditText.Text += "DownloadHomepage method continues after async call. . . . .\n";
// After contentTask completes, you can calculate the length of the string.
int exampleInt = contents.Length;
ResultEditText.Text += "Downloaded the html and found out the length.\n\n\n";
ResultEditText.Text += contents; // just dump the entire HTML
return exampleInt; // Task<TResult> returns an object of type TResult, in this case int
}
authenticate()是一种异步方法,因此您需要等待它
string content = await myClient.authenticate( username, password );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.