简体   繁体   English

如何处理来自httpclient的数据

[英]How to handle data from httpclient

I'm working on a new Windows Phone 8 app. 我正在开发一个新的Windows Phone 8应用程序。 I'm connecting to a webservice which returns valid json data. 我正在连接到一个返回有效json数据的webservice。 I'm using longlistselector to display the data. 我正在使用longlistselector来显示数据。 This works fine when i'm using the string json in GetAccountList(); 当我在GetAccountList()中使用字符串json时,这很好用; but when receiving data from the DataServices class i'm getting the error "Cannot implicitly convert type 'System.Threading.Tasks.Task'to string". 但是当从DataServices类接收数据时,我收到错误“无法隐式转换类型'System.Threading.Tasks.Task'到字符串”。 Don't know what goes wrong. 不知道出了什么问题。 Any help is welcome. 欢迎任何帮助。 Thanks! 谢谢!

DataServices.cs DataServices.cs

    public async static Task<string> GetRequest(string url)
    {
        HttpClient httpClient = new HttpClient();

        await Task.Delay(250);

        HttpResponseMessage response = await httpClient.GetAsync(url);
        response.EnsureSuccessStatusCode();
        string responseBody = await response.Content.ReadAsStringAsync();
        Debug.WriteLine(responseBody);
        return await Task.Run(() => responseBody);
    }

AccountViewModel.cs AccountViewModel.cs

 public static List<AccountModel> GetAccountList()
    {
        string json = DataService.GetRequest(url);
        //string json = @"{'accounts': [{'id': 1,'created': '2013-10-03T16:17:13+0200','name': 'account1 - test'},{'id': 2,'created': '2013-10-03T16:18:08+0200','name': 'account2'},{'id': 3,'created': '2013-10-04T13:23:23+0200','name': 'account3'}]}";
        List<AccountModel> accountList = new List<AccountModel>();

        var deserialized = JsonConvert.DeserializeObject<IDictionary<string, JArray>>(json);

        JArray recordList = deserialized["accounts"];


        foreach (JObject record in recordList)
        {
            accountList.Add(new AccountModel(record["name"].ToString(), record["id"].ToString()));
        }

        return accountList;
    }

UPDATE: I changed it slightly and works like a charm now. 更新:我稍微改变它,现在就像一个魅力。 Thanks for your help! 谢谢你的帮助! DataServices.cs DataServices.cs

     //GET REQUEST
    public async static Task<string> GetAsync(string url)
    {
        var httpClient = new HttpClient();

        var response = await httpClient.GetAsync(url);

        string content = await response.Content.ReadAsStringAsync();

        return content;
    }

AccountViewModel.cs AccountViewModel.cs

    public async void LoadData()
    {
        this.Json = await DataService.GetAsync(url);
        this.Accounts = GetAccounts(Json);
        this.AccountList = GetAccountList(Accounts);
        this.IsDataLoaded = true;
    }

    public static IList<AccountModel> GetAccounts(string json)
    {
        dynamic context = JObject.Parse(json);

        JArray deserialized = (JArray)JsonConvert.DeserializeObject(context.results.ToString());

        IList<AccountModel> accounts = deserialized.ToObject<IList<AccountModel>>();

        return accounts;
    }

    public static List<AlphaKeyGroup<AccountModel>> GetAccountList(IList<AccountModel> Accounts)
    {
        List<AlphaKeyGroup<AccountModel>> accountList = AlphaKeyGroup<AccountModel>.CreateGroups(Accounts,
                System.Threading.Thread.CurrentThread.CurrentUICulture,
                (AccountModel s) => { return s.Name; }, true);

        return accountList;
    }

That line is your problem: 那条线是你的问题:

return await Task.Run(() => responseBody);

Did you try that? 你试过吗? :

return responseBody;

Try this too: 试试这个:

public async static List<AccountModel> GetAccountList()
{
    string json = await DataService.GetRequest(url);
    ...
}

A few things here. 这里有一些事情。 First the error 首先是错误

Cannot implicitly convert type 'System.Threading.Tasks.Task' to string This error is coming from the call to DataService.GetRequest(url) . 无法将类型'System.Threading.Tasks.Task'隐式转换为字符串此错误来自对DataService.GetRequest(url)的调用。 This method does return a string. 此方法确实返回一个字符串。 Tt returns a Task where T is a string. Tt返回一个任务 ,其中T是一个字符串。 There are many ways that you can use the result of this method. 有许多方法可以使用此方法的结果。 the first (and best/newest) is to await the call to the method. 第一个(最好的/最新的)是等待对方法的调用。

string json = await DataService.GetResult(url);

Making this change requires you to add the async keyboard to your method 进行此更改需要您将async键盘添加到方法中

public async static List<AccountModel> GetAccountList()

This is the new async/await pattern. 这是新的异步/等待模式。 Adding these words tells the compiler that the method cal is asynchronous. 添加这些单词告诉编译器方法cal是异步的。 It allows you to make asynchronous calls but write code as if it is synchronous. 它允许您进行异步调用,但编写代码就像它是同步的一样。 The other ways to call the method are to work the Task object directly. 调用该方法的其他方法是直接使用Task对象。

// First is to use the Result property of the Task
// This is not recommended as it makes the call synchronous, and ties up the UI thread
string json = DataService.GetResult(url).Result;

// Next is to continue work after the Task completes.
DataService.GetResult(url).ContinueWith(t =>
{
    string json = t.Result;
    // other code here.
};

Now for the GetResult method. 现在为GetResult方法。 Using the async/await pattern requires you to return Task from methods. 使用async / await模式要求您从方法返回Task。 Even though the return type is Task, your code should return T. So as Krekkon mentioned, you should change the return line to 即使返回类型是Task,您的代码也应该返回T.所以,正如Krekkon所提到的,您应该将返回行更改为

return responseBody;

Here is a great article about returning Task from an async method. 这是一篇关于从异步方法返回Task的好文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM