0

I'm trying to return value from async html helper but it is giving following string instead of desired values.

"System.Threading.Tasks.Task+WhenAllPromise`1[System.Decimal]"

Method:

public async static Task<decimal> CalculateCurrency(this HtmlHelper helper, decimal amount, string from, string country)
    {
        if (await getValue(country))
        {
            string fromCurrency = string.IsNullOrEmpty(from) ? "USD" : from;
            string toCurrency = country;
            WebClient client = new WebClient();
            string url = string.Format("http://finance.yahoo.com/d/quotes.csv?e=.csv&f=sl1d1t1&s={0}{1}=X", fromCurrency.ToUpperInvariant(), toCurrency.ToUpperInvariant());
            Stream response = await client.OpenReadTaskAsync(url);
            StreamReader reader = new StreamReader(response);
            string yahooResponse = await reader.ReadLineAsync();
            response.Close();
            if (!string.IsNullOrWhiteSpace(yahooResponse))
            {
                string[] values = Regex.Split(yahooResponse, ",");
                if (values.Length > 0)
                {
                    decimal rate = System.Convert.ToDecimal(values[1]);
                    string res = string.Format("{0:0.00}", rate * amount);
                    return decimal.Parse(res);
                 }
            }
            return decimal.Zero;
        }
        return decimal.Zero;
    }

Call HTML Helper:

@Html.CalculateCurrency(22, "USD", "EUR")
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
DevWithSigns
  • 725
  • 16
  • 33
  • Its not a good idea to call asynchronous code from a view. – DavidG Jul 12 '14 at 01:50
  • @DavidG how i can solve this issue? i want that method to run asynchronous – DevWithSigns Jul 12 '14 at 02:01
  • Do the asynchronous work inside the method but return synchronously. – DavidG Jul 12 '14 at 02:04
  • @DavidG i want to improve application performance thats why i used async method, is there any other way to do this? or how i can do this with this method? – DevWithSigns Jul 12 '14 at 02:10
  • @Usama Async code isn't intended to improve performance, it's intended to improve *responsiveness*. For what you're doing here, the best approach would probably be to have an async controller method, which you call asynchronously from your front end via AJAX. – Daniel Mann Jul 12 '14 at 02:14
  • @DanielMann can u please guide me with code how i can do this? – DevWithSigns Jul 12 '14 at 02:17
  • Yes, @DanielMann beat me to the answer there! :) – DavidG Jul 12 '14 at 02:17
  • 1
    @Usama I'm sorry, but I'm not going to write your code for you. I've given you a nudge in the right direction -- start researching! If you hit any problems, feel free to post another question! – Daniel Mann Jul 12 '14 at 02:21

1 Answers1

4

Views don't support asynchronous methods. So as result you get result of default .ToString() function for type of result which indeed returns just type name.

Options:

  • move code to controller and call in from asynchronous top level (non-child) action with await. Pass data to view via model or ViewBag
  • convert to real synchronous code if you must call it from the view or child action
  • if not possible try .Result, but watch out for deadlocks. See await vs Task.Wait - Deadlock? for details/links.

Note: moving async code to child action will not help.

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179