【问题标题】:Consuming WebAPI in blazor with authentication在 blazor 中使用带有身份验证的 WebAPI
【发布时间】:2020-02-03 12:06:14
【问题描述】:

我在创建 ASP.NET WebAPI 项目时使用 VS 2019 提供的天气预报数据的基本模板,并添加了一些非常基本的用户登录身份验证和对 JWT 令牌的支持,一切正常。

我正在尝试创建一个 blazor 客户端项目来使用 API 并在页面上显示数据。 AFAIK Blazor 不支持 localstorage 所以我使用 Blazored LocalStorage 包来给我这个能力。我的问题源于在服务器端 blazor (https://github.com/aspnet/AspNetCore/issues/13396) 中无法通过 OnInitializedAsync() 使用 JS,因此我不确定如何使用这些 web api 调用。因为这会产生一个空引用异常

protected override async Task OnInitializedAsync()
{
    var client = HttpFactory.CreateClient();
    var token = await LocalStorage.GetItemAsync<string>("authToken");
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    var response = await client.GetAsync("url/WeatherForecast");
    var str = await response.Content.ReadAsStringAsync();
    Items = JsonConvert.DeserializeObject<IEnumerable<WeatherForecast>>(str);
}

一个建议是使用 OnAfterRenderAsync() 方法来调用它们,因为那时 JS 已经准备好了。哪个半工作但显然 UI 不匹配,因为它需要刷新 - 但是要手动刷新它似乎我必须调用 StateHasChanged();这反过来又再次调用 OnAfterRender 方法,结果我不得不进行检查,但这最终感觉非常糟糕。

private bool hasRendered;
protected override async Task OnAfterRenderAsync(bool _)
{
    if (!hasRendered) return;
    var client = HttpFactory.CreateClient();
    var token = await LocalStorage.GetItemAsync<string>("authToken");
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    var response = await client.GetAsync("https://url/WeatherForecast");
    var str = await response.Content.ReadAsStringAsync();
    Items = JsonConvert.DeserializeObject<IEnumerable<WeatherForecast>>(str);

    StateHasChanged();

    hasRendered = true;
}

使用具有身份验证功能的 API 并在客户端正确显示数据的正确方法是什么?

附带问题 HttpClient 似乎不能在服务器端注入,建议使用 HttpClientFactory - 在每个请求上创建一个客户端或在整个客户端项目中创建一个单例并重用是个好主意吗?

【问题讨论】:

  • 您表示您正在创建一个“blazor 客户端项目”,但后来又说“我的问题源于在服务器端 blazor 中无法通过 OnInitializedAsync() 使用 JS”?我是不是误会了什么?
  • 在这个意义上向我的客户道歉,我的意思是一个 UI 排序客户端。这是一个服务器端的 Blazor 项目。
  • 如果我使用的是服务器端 Blazor,则无需进行任何 http 调用 :) 问题解决了,对吧?
  • 什么意思?如何在没有 http 请求的情况下请求 API 调用?
  • 使用服务器端 Blazor,您只需直接调用服务器端控制器。这是完全安全的。看;创建逐步端到端数据库服务器端 Blazor 应用程序blazorhelpwebsite.com/Blog/tabid/61/EntryId/4318/…

标签: c# blazor blazor-server-side


【解决方案1】:

第一季度

一个建议是使用 OnAfterRenderAsync() 方法来调用它们,因为那时 JS 已经准备好了。哪个半工作但显然 UI 不匹配,因为它需要刷新 - 但是要手动刷新它似乎我必须调用 StateHasChanged(); 这又会再次调用 OnAfterRender 方法,因此我不得不进行检查,但这最终感觉非常糟糕。

所有人都有同样的问题,因为在Lifecycle methods,新的OnAfterRenderAsyncfirstRender parm 记录在案:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await ... /// your auth code here.
    }
}

第二季度

附带问题 HttpClient 似乎不能在服务器端注入,建议使用 HttpClientFactory - 在每个请求上创建一个客户端或在整个客户端项目中创建一个单例并重用是个好主意吗?

简化:我建议您为后端调用创建两个外部库:一个使用 http 请求(用于 blazor wasm 托管模型),另一个仅调用 c# 后端函数(用于 blazor 服务器)。两者都具有用于后端调用的通用接口。使用DI to set right library for each hosted model

【讨论】:

  • 该死的太丑了 - 我很惊讶在设置新数据时没有类似于 WPF 的 OnPropertyChanged 事件。
猜你喜欢
  • 2021-04-20
  • 1970-01-01
  • 2014-07-05
  • 2018-01-28
  • 1970-01-01
  • 2021-04-30
  • 2020-09-10
  • 2017-05-08
  • 2019-04-28
相关资源
最近更新 更多