Blazor Before Render Call Function

泪湿孤枕 提交于 2020-03-28 06:55:11

问题


I am running an Blazor Server-Side client, which contacts an api gets a token and saves it in local storage. When i route to a second page i want to check if token is there so !null. I can't find the right place to check this or where. I tried on a layout and with overriding OnInitialized and it works but you get this horrid flicker where the ui is loaded and then the check is finished so it redirects, basically the user partially sees the page they shouldnt have access too. Where should i be calling this check or how should i be doing this.

Any suggestions welcome. Thanks and sorry if im not so clear new to Blazor.


回答1:


You can create a service whose functionality is to save the token in the local storage, and retrieve it when needed, as for instance, when you want to call a secured Web Api end point...

Shall we call it TokenProvider ? Please, define a class named so... The following is the code for such a class:

TokenProvider.cs

using Microsoft.JSInterop;


public class TokenProvider
{
    private readonly IJSRuntime JSRuntime;

    public TokenProvider(IJSRuntime JSRuntime)
    {
        this.JSRuntime= JSRuntime;
    }

    public async Task<string> GetTokenAsync()
        => await JSRuntime.InvokeAsync<string>("localStorage.getItem", 
                                                         "authToken");

    public async Task SetTokenAsync(string token)
    {
        if (token == null)
        {
            await JSRuntime.InvokeAsync<object>("localStorage.removeItem", 
                                                            "authToken");
        }
        else
        {
            await JSRuntime.InvokeAsync<object>("localStorage.setItem", 
                                                   "authToken", token);
        }

    }

 }

Note that a IJSRuntime service is injected into the constructor of the service. Next you should add this service to the DI container. Add the following code in your Startup class

services.AddScoped<TokenProvider>();

Now you can use the TokenProvider in your component:

Suppose you need to call your secured Web Api end point that returns an array of WeatherForcast objects to be used in your FetchData component (FetchData.razor, default template). To make this works, you need to: * inject the TokenProvider service into your FetchData component: Place this @inject directive at the top of the page like this:

@page "/fetchdata"

@inject TokenProvider TokenProvider

And in the OnInitializedAsync life cycle method do this:

@code {
    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        var httpClient = clientFactory.CreateClient();
        httpClient.BaseAddress = new Uri("https://localhost:44381/");

        var token = await TokenProvider.GetTokenAsync();
        forecasts = await httpClient.GetJsonAsync<WeatherForecast[]> 
             ("api/weatherforecast?startDate=12/29/2019", new 
                         AuthenticationHeaderValue("Bearer", token));
    }
}

TODO:

1. Add @inject IHttpClientFactory clientFactory at the top of the page. This allows you to inject the IHttpClientFactory service which provides the HttpClient service object to make call to your Web Api. You should also add the IHttpClientFactory service to the DI container in the Startup.ConfigureServices method: services.AddHttpClient();

  1. Here is the using directive you may need:

    @using System.Text; @using System.Text.Json; @using System.Text.Json.Serialization; @using Microsoft.AspNetCore.Components; @using System.Net.Http; @using System.Net.Http.Headers; @using Microsoft.Net.Http;

  2. Did you notice that the token is sent within the AuthenticationHeaderValue ? To be able to use this object and related services, add services.AddAuthorizationCore(); to the Startup.ConfigureServices method

By now your Startup.ConfigureServices method should look something like this:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
        services.AddServerSideBlazor();
        services.AddAuthorizationCore();
         services.AddScoped<TokenProvider>();
        services.AddHttpClient();
    }

Hope this helps...



来源:https://stackoverflow.com/questions/60279232/blazor-before-render-call-function

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