Reputation: 4760
I am trying to bring up a simple .NET Core 2.0 Web Application with Razor pages. The page is connected to an equally simple Core 2.0 Web API. I have a simple class:
public class About : PageModel
{
private ServiceProxy serviceProxy;
public About(ServiceProxy serviceProxy)
{
this.serviceProxy = serviceProxy;
}
public IEnumerable<ProductViewModel> Values { get; set; }
public async void OnGetAsync()
{
this.Values = await this.serviceProxy.GetValuesAsync();
}
}
And the page is also simple:
@page
@model About
@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h3>@Model.Message</h3>
@foreach (var product in @Model.Values)
{
<p>@product.Name</p>
}
However, the page displays before the OnGetAsync()
method can populate the 'Values' list. This seems like such a common operation, but I can't find any discussion of it (I've also tried iterating over an async 'GetValues()' method).
How are CSHTML pages supposed to interact with a Web API that may take a few seconds to return results?
Upvotes: 14
Views: 13076
Reputation: 247591
That is because of the async void
, which is basically a fire and forget, and should be avoided. The page will load before the function has time to complete as they will be executing in parallel.
Change the signature to async Task
so that the Page can await the action to complete.
public async Task<IActionResult> OnGetAsync() {
this.Values = await this.serviceProxy.GetValuesAsync();
return Page();
}
Reference Introduction to Razor Pages in ASP.NET Core
Upvotes: 22