Ошибка взаимодействия JavaScript при вызове JavaScript из OnInitializedAsync Blazor

Я слежу за примером приложения от NDC Oslo, которое представляет собой это приложение: https://github.com/SteveSandersonMS/presentation-2019-06-NDCOslo/tree/master/demos/MissionControl. Это реализует JWT как аутентификацию и авторизацию. Однако, когда я пытался скопировать реализацию кода в серверный Blazor, я получаю сообщение об ошибке, когда пытаюсь сохранить токен JWT из локального хранилища, описанного ниже "

JavaScript interop calls cannot be issued at this time. This is because the component is being 
statically rendererd. When prerendering is enabled, JavaScript interop calls can only be performed 
during the OnAfterRenderAsync lifecycle method.

Вот мой код блейзера

protected override async Task OnInitializedAsync()
{
    var token = await TokenProvider.GetTokenAsync();
    Branches = await Http.GetJsonAsync<List<BranchDto>>(
        "vip/api/lookup/getbranches",
        new AuthenticationHeaderValue("Bearer", token));
}

Ошибка возникает

public async Task<string> GetTokenAsync()
{
   //Code Omitted for brevity 
   //This line of code is equivalent to the IJSRuntime.Invoke<string>("localstorage.getitem","authToken") 
   //change to use Blazore.LocalStorage.
    var token = await _localStorageService.GetItemAsync<string>("authToken");
    return token;
 }

Я попытался выполнить код на OnAfterRenderAsync (bool firstRender), и ошибка исчезла, но сетка, привязанная к запросу API, не отображается. Запрос API должен заполнить источник данных для сетки, которым должен быть OnInitializedAsync. Есть ли способ обойти это?

Обновление! Я переместил код OnAfterRenderAsync и добавил метод StateHasChanged и получил желаемое поведение. Я забыл, что соединение для рендеринга было соединением signalR.


person Edu Cielo    schedule 26.04.2020    source источник
comment
@poke Мне было интересно, почему пример NDC работает нормально. Хорошая уловка, указав на меня.   -  person Edu Cielo    schedule 26.04.2020
comment
Демонстрационная версия работает на ASP.NET Core 3.0, возможно, даже в предварительной версии, поэтому возможно, что там что-то немного изменилось.   -  person poke    schedule 26.04.2020
comment
Я согласен. Поскольку это указано в их документации, я думаю, что буду следовать обходному пути, в первую очередь, с тем, как выполняется токен и авторизация.   -  person Edu Cielo    schedule 26.04.2020


Ответы (1)


Согласно « Обнаруживать, когда приложение Blazor Server выполняет предварительную отрисовку », вы можете безопасно запускать код взаимодействия только в OnAfterRenderAsync методе жизненного цикла.

Однако, поскольку это выполняется после цикла рендеринга, вам нужно будет уведомить свой компонент о повторном рендеринге с помощью StateHasChanged() после завершения вашего асинхронного процесса:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        var token = await TokenProvider.GetTokenAsync();
        Branches = await Http.GetJsonAsync<List<BranchDto>>(
            "vip/api/lookup/getbranches",
            new AuthenticationHeaderValue("Bearer", token));

        StateHasChanged();
    }
}
person poke    schedule 26.04.2020