Calling async methods in Blazor view

南楼画角 提交于 2020-05-23 10:03:23

问题


I have a server-side blazor client and I'm trying to modify the MainLayout razor page by having a Login check. I'm currently using Blazored for localstorage saving, and I'm currently using to see if a token is saved to see if user is logged in, however I'm not sure how I translate this in the if statement in razor page because it wants async method.

My login check is pretty simple as shown below.

public async Task<bool> IsLoggedIn()
{
    return await m_localStorage.ContainKeyAsync("token").ConfigureAwait(false);
}

In my Razor page I'm doing this statement check - which obvious doesn't work as there's no async modifier

@if (!await AppState.IsLoggedIn()) //Requires async modifier
{
    <a href="Login" target="_blank">Login</a>
}

I've also tried doing it using the .Result property, but this results in an exception thrown: (System.AggregateException: 'Information: Executed an implicit handler method, returned result Microsoft.AspNetC)' with an inner-exception -> NullReferenceException: Object reference not set to an instance of an object.

But from what I can see AppState is injected correctly and the local storage seems to be injected correctly in AppState.

@if (!AppState.IsLoggedIn().Result)
{
    <a href="Login" target="_blank">Login</a>
}

So my question is what is the correct way to approach this, is there a way to execute async methods in razor pages?


回答1:


is there a way to execute async methods in razor pages?

No, there isn't a way to use await in a Razor component. This is because you can't do async work as part of the rendering of the component.

Incidentally, the local storage mechanism provided by the Blazor team supports data protection, and is recommended for use by Steve Sanderson.

Note: The async Lifecycle methods of the component are where async work is done, and thus you can design your code accordingly, as for instance, calling AppState.IsLoggedIn() from OnInitializedAsync, and assigning the returned value to a local variable which can be accessed from your views.




回答2:


AsyncComponent.razor

    @typeparam TResult
    @typeparam TInput
    @if (Result != null)
    {
        @DataReadyFragment(Result)
    }
    else if (DataMissingFragment != null)
    {
        @DataMissingFragment
    }
    @code {
        [Parameter] public RenderFragment<TResult> DataReadyFragment { get; set; }
        [Parameter] public RenderFragment DataMissingFragment { get; set; }
        [Parameter] public Func<TInput, Task<TResult>> AsyncOperation { get; set; }
        [Parameter] public TInput Input { get; set; }
        TResult Result { get; set; }

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if(firstRender)
AsyncOperation.Invoke(Input).ContinueWith(t => { Result = t.Result; InvokeAsync(StateHasChanged); });
        }
    }

Usage

<AsyncComponent TResult="User" TInput="string" Input="Pa$$W0rd" AsyncOperation="@AsyncMethodName">
    <DataReadyFragment Context="result">
        @if(result.IsLoggedIn)
         {
           <h3>Logged-In , Username:@result.Name</h3>
         }
         else
         {
          <h3>Wrong Password</h3>
         }
    </DataReadyFragment>
    <DataMissingFragment>
        <h3>Please Login :)</h3>
    </DataMissingFragment>
</AsyncComponent>


来源:https://stackoverflow.com/questions/58358900/calling-async-methods-in-blazor-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!