在Blazor视图中调用异步方法

时间:2019-10-12 21:56:29

标签: c# blazor blazor-server-side

我有一个服务器端的blazor客户端,我试图通过登录检查来修改MainLayout剃刀页面。我目前正在使用Blazored进行本地存储保存,并且目前正在查看是否保存了令牌以查看用户是否已登录,但是我不确定如何在razor页面的if语句中对此进行翻译需要异步方法。

我的登录检查非常简单,如下所示。

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

在我的Razor页面中,我正在执行此语句检查-由于没有异步修饰符,这显然不起作用

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

我也尝试过使用.Result属性来执行此操作,但这会引发异常:(System.AggregateException:'Information:执行了隐式处理程序方法,返回结果Microsoft.AspNetC)',并且带有内部异常-> NullReferenceException:对象引用未设置为对象的实例。

但是从我看到的内容来看,AppState已正确注入,而本地存储似乎已正确注入了AppState。

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

所以我的问题是解决此问题的正确方法是什么,有没有一种方法可以在剃须刀页面中执行异步方法?

3 个答案:

答案 0 :(得分:2)

  

有没有一种方法可以在剃须刀页面中执行异步方法?

否,在Razor组件中没有使用await的方法。这是因为您不能在组件呈现过程中进行异步工作。

顺便说一下,Blazor团队提供的本地存储机制支持数据保护,建议Steve Sanderson使用。

注意:组件的异步生命周期方法是完成异步工作的位置,因此您可以相应地设计代码,例如,从OnInitializedAsync调用AppState.IsLoggedIn()并将返回的值分配给局部变量可以从您的视图中访问。

答案 1 :(得分:1)

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); });
        }
    }

用法

<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>

答案 2 :(得分:0)

基于 LazZiya 示例,对我有用。在我的情况下,事件不像组件支持的那样异步,但我需要等待的调用。使用此示例,我可以根据模型从调用中返回数据。

public string Name => Task.Run(() => Service.GetNameAsync()).GetAwaiter().GetResult();

我最终得到了这个,它就像一个魅力。

Task<AssessmentResponsesModel> task = Task.Run(() => _IAssessmentResponse.CreateAsync(APIPathD, argsItem, token).GetAwaiter().GetResult());