如何处理来自httpclient的数据。

5
我正在开发一个新的Windows Phone 8应用程序。我正在连接到一个返回有效json数据的Web服务。我使用longlistselector来显示数据。当我在GetAccountList()中使用字符串json时,这个工作很好;但是当从DataServices类接收数据时,我会收到错误“不能隐式转换类型'System.Threading.Tasks.Task'到字符串”。不知道出了什么问题。欢迎任何帮助。谢谢!
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

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

更新:我稍微修改了它,现在完美运行。谢谢你的帮助! 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

    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;
    }
2个回答

1
那一行是你的问题:
return await Task.Run(() => responseBody);

你尝试过那个吗?:

return responseBody;

Try this too:

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

还是一样的问题。在GetAccountList()函数中,"string json = DataService.GetRequest(url);"这行代码报错。 - marlonlaan
是的,它会因为异步而产生错误。但请在GetReuquest方法中设置断点并告诉我,“真正”的异常抛出在哪里 :) - Krekkon

0

这里有几件事情。首先是错误信息:

无法隐式转换类型 'System.Threading.Tasks.Task' 为字符串。 这个错误来自于对 DataService.GetRequest(url) 的调用。这个方法确实返回一个字符串,但它返回的是一个 Task,其中 T 是字符串类型。你可以使用多种方式来使用这个方法的结果。第一种(也是最好/最新的)方法是等待调用该方法。

string json = await DataService.GetResult(url);

进行此更改需要您在方法中添加 async 关键字。
public async static List<AccountModel> GetAccountList()

这是新的async/await模式。添加这些关键字告诉编译器该方法调用是异步的。它允许您进行异步调用,但编写代码时就好像它是同步的。 调用这个方法的其他方法是直接处理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.
};

现在来看GetResult方法。使用async/await模式需要你从方法中返回Task。尽管返回类型是Task,但你的代码应该返回T。正如Krekkon所提到的,你应该将返回行更改为:
return responseBody;

这是一篇关于从异步方法返回Task的优秀文章

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接