How to handle data from httpclient

Refresh

November 2018

Views

5.3k time

5

I'm working on a new Windows Phone 8 app. I'm connecting to a webservice which returns valid json data. I'm using longlistselector to display the data. This works fine when i'm using the string json in GetAccountList(); but when receiving data from the DataServices class i'm getting the error "Cannot implicitly convert type 'System.Threading.Tasks.Task'to string". Don't know what goes wrong. Any help is welcome. Thanks!

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

UPDATE: I changed it slightly and works like a charm now. Thanks for your help! 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 answers

1

Эта линия ваша проблема:

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

Пробовали ли вы что? :

return responseBody;

Попробуйте также:

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

Несколько вещей здесь. Первая ошибка

Не может неявно преобразовать тип «System.Threading.Tasks.Task» нанизывать Эта ошибка происходит из вызова DataService.GetRequest(url). Этот метод не возвращает строку. Tt возвращает задачу , где Т представляет собой строку. Есть много способов , которые вы можете использовать результат этого метода. первый (и лучший / новейший) является ждать вызов метода.

string json = await DataService.GetResult(url);

Выполнение этих изменений требует , чтобы добавить asyncклавиатуру к методе

public async static List<AccountModel> GetAccountList()

Это новый асинхронной / ждут картины. Добавление этих слов указывает компилятору, что метод кал является асинхронным. Это позволяет делать асинхронные вызовы, но писать код так, как будто это происходит синхронно. Другие способы для вызова метода должны работать объект 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. Использование асинхр / ждать модель требует, чтобы вернуться Задачей из методов. Даже если возвращаемый тип задачи, ваш код должен возвращать T. Так как уже упоминалось Krekkon, вы должны изменить линию возврата

return responseBody;

Вот большая статья о возвращении задачи от метода асинхронного.