0

I am using async/await, and calling an async method from one of my views and I need to wait until it finishes. I've seen a lot of examples for ASP.NET MVC, where you can just put an "async" into the signature of your action. But I haven't seen any examples for ASP.NET WebPages.

Do I just call "Wait()" on the returned task inside my Razor view? I've seen recommendations against Wait().

Please give me some references/examples on how to properly call async methods from within a Razor view in WebPages.

svick
  • 236,525
  • 50
  • 385
  • 514
Arman Bimatov
  • 1,789
  • 4
  • 24
  • 31
  • `async/await` is a core feature, not tied to MVC. Also, `async` doesn't make a method asynchronous, it allows you to `await` on already asynchronous methods. Just add the proper keywords to your methods, as you would with MVC – Panagiotis Kanavos Oct 09 '14 at 16:34
  • I do have all the proper keywords on my methods. I just need to know how do I properly call them from my views? – Arman Bimatov Oct 09 '14 at 16:38
  • possible duplicate of [Use of await in Razor views](http://stackoverflow.com/questions/19182349/use-of-await-in-razor-views) – Panagiotis Kanavos Oct 10 '14 at 07:13

1 Answers1

4

calling an async method from one of my views

Don't call methods from within the view. The view should really just be binding to data that's on the model. If there's an asynchronous operation to be performed to fetch the model's data, perform it in the controller when populating the model.

As a contrived example:

public class MyViewModel
{
    public string SomeValue { get; set; }
}

and in the controller:

var model = new MyViewModel
{
    SomeValue = await GetTheValue();
};
return View(model);

and in the view:

@Model.SomeValue

The model should essentially be "complete" when it's given to the view to render, and the view should just be rendering it. The asynchronous operations should be in the controller.


As an alternative to putting too much code in the controller and keeping it in the model, you can move an asynchronous operation to some kind of initialization on the model:

public class MyViewModel
{
    public string SomeValue { get; private set; }

    public async Task Initialize()
    {
        SomeValue = await GetTheValue();
    }
}

Then in your controller you'd invoke that:

var model = new MyViewModel();
await model.Initialize();
return View(model);

Or perhaps an asynchronous factory on the model:

public class MyViewModel
{
    public string SomeValue { get; private set; }

    private MyViewModel() { }

    public static async MyViewModel Create()
    {
        return new MyViewModel
        {
            SomeValue = await GetTheValue()
        };
    }
}

Then in the controller:

var model = await MyViewModel.Create();
return View(model);

There are a number of ways to go about this, really. The main thing is to keep the asynchronous operations out of the view, whose only job should be to render the UI once the model is complete.

David
  • 208,112
  • 36
  • 198
  • 279
  • well, that means I have to rewrite my project as MVC. Is there a way to do this with WebPages though (no models or controllers)? – Arman Bimatov Oct 09 '14 at 16:46
  • @ArmanBimatov: Oh, I thought this was MVC. Either way, the same concept applies. The rendering engine should just be rendering the data that it's been given. It shouldn't be calling asynchronous operations. Is this more like WebForms instead? In that case the code-behind would be where the asynchronous operations take place. – David Oct 09 '14 at 16:49
  • @ArmanBimatov: If there's no "code-behind" then you can *try* something like `var someValue = await GetTheValue();` or `var someValue = GetTheValue().Result;` It's kind of a crap-shoot since this "WebPages" thing seems to be obscuring the server-side application host structure. The former option might not be syntactically valid (if the context of the rendering engine isn't `async`), the latter may result in a deadlock. If the system is growing in any measurable complexity, "WebPages" may not be the best approach. – David Oct 09 '14 at 16:58
  • I will be the first to say: it is not the best approach haha. And regarding your two concerns - they are both true in my case. – Arman Bimatov Oct 09 '14 at 18:18
  • @ArmanBimatov: I've tried Googling, and documentation and samples seem a bit light on "WebPages" (which is admittedly a pretty generic term, so it's tough to search). It really sounds like either the top-level code host isn't asynchronous or hides its asynchronicity. It really sounds like a switch to MVC would bring about a lot of benefits for not a lot of investment, since I bet *most* of the code can be pasted into MVC views as-is. – David Oct 09 '14 at 18:20
  • you're right, it wouldn't be too hard to switch. Still a bit of a hassle - creating project, setting up build process etc. – Arman Bimatov Oct 09 '14 at 18:31
  • I'd like to see you call `Html.RenderPartialAsync` from the controller. – ProfK Mar 06 '17 at 07:31