I have a razor page that shows a 'Please wait' box and the OnGet
method does some stuff that might take a few seconds and ends with a LocalRedirect
.
The razor code:
@page
@inject IStringLocalizer<Startup> localizer
<div class="login-page">
<div class="login-box">
<div class="card">
<div class="card-body login-card-body">
<div class="help-block text-center">
<div class="spinner-border" role="status" />
</div>
<p class="login-box-msg">@localizer["PleaseWait"]</p>
</div>
</div>
</div>
</div>
And the code-behind:
public async Task<IActionResult> OnGet()
{
//Do some stuff that takes a few seconds...
return LocalRedirect("/Dashboard");
}
Everything is working apart from the page first being shown and then executing the code.
Is it possible to first render the page (so that the users can see that something is happening) and then execute the code in the OnGet
?
Move your long async
routines from OnGet
to a number of named handler methods. Allow the page to render a "please wait" message and use client-side code (jQuery AJAX or plain Fetch) to call the named handlers. Keep track of when they complete and when all have completed, redirect to the other page.
Here's an example where the OnGet
simply renders the page (can include a "please wait" message"), and a number of named handlers simulate routines of varying length:
public void OnGet()
{
}
public async Task OnGetTwoSeconds()
{
await Task.Delay(2000);
}
public async Task OnGetThreeSeconds()
{
await Task.Delay(3000);
}
public async Task OnGetFiveSeconds()
{
await Task.Delay(5000);
}
The following script goes in the Razor page itself. It consists of three variables for tracking task completion and a method that redirects to the home page when all three have completed. Each of the named handlers is called by the code and sets its tracking variable to true on completion as well as calling the redirect
function:
@section scripts{
<script>
let twosecondsdon = false;
let threesecondsdone = false;
let fivesecondsdone = false;
function redirect(){
if (twosecondsdone && threesecondsdone && fivesecondsdone) {
location.href = '/';
}
}
fetch('?handler=TwoSeconds').then(() => {
twosecondsdone = true;
redirect();
})
fetch('?handler=ThreeSeconds').then(() => {
threesecondsdone = true;
redirect();
})
fetch('?handler=FiveSeconds').then(()=>{
fivesecondsdone = true;
redirect();
})
</script>
}
When all three complete, the redirect
function does its thing.