通过使用c#和HttpClient调用REST API检索JSON内容

本文关键字:API REST 检索 JSON 内容 调用 HttpClient | 更新日期: 2023-09-27 17:51:15

我正在尝试使用Xamarin和c#进行一些移动开发。我正在为Android应用程序构建一个简单的登录屏幕,我正在使用HttpClient来进行实际呼叫,但我被困在一些细节上以使其工作。

我已经设置了一个简单的Client类,代表我的API客户端:

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;
            }
        }
    }
}

可以看到,authenticate方法使用POST在服务器上创建一个新的会话。/auth端点返回一个带有令牌和超时值的JSON blob。

authenticate方法是这样被调用的:

Client myClient = new Client();
Task<string> contentTask = myClient.authenticate( username, password );
var content = contentTask.ToString();
Console.Out.WriteLine(content);

我的content从不输出任何东西。我显然(毫无疑问)做错了很多事情。

我怎么能让我的authenticate方法返回我期望的JSON字符串?

我一直在使用这些来源的灵感:

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

通过使用c#和HttpClient调用REST API检索JSON内容

由于您返回的是Task而不仅仅是string,因此您需要等待myclient.authenticate方法。

如果返回string,则不必等待。我认为这在你的情况下是可能的,只需将返回类型从Task<string>更改为string

你的客户端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;
            }
        }
    }

使用客户端:

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);
}
示例代码已经存在于灵感来源
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 );