Domanda

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;
    }
È stato utile?

Soluzione

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

Altri suggerimenti

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). This method does return a string. Tt returns a Task where T is a string. 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

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. 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.

// 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. Using the async/await pattern requires you to return Task from methods. Even though the return type is Task, your code should return T. So as Krekkon mentioned, you should change the return line to

return responseBody;

Here is a great article about returning Task from an async method.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top