凭认证使用WebAPI,

时间:2019-10-05 12:50:33

标签: c# blazor blazor-server-side

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

我正在尝试创建一个blazor客户端项目以使用该API并在页面上显示数据。 AFAIK Blazor不支持本地存储,因此我正在使用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-在每个请求上创建客户端还是创建一个单例并在整个客户端项目中重复使用是一个好主意吗? / p>

1 个答案:

答案 0 :(得分:1)

第一季度

  

一个建议是使用OnAfterRenderAsync()方法来调用它们,因为届时JS将准备就绪。哪种方法可行,但显然UI不匹配,因为需要刷新-但是要手动刷新,看来我必须调用StateHasChanged();。 又会再次调用OnAfterRender方法,结果我不得不进行检查,但这最终让人感到难以置信。

所有存在相同问题的人,因为在Lifecycle methods,新的OnAfterRenderAsyncfirstRender参数已被记录:

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

第二季度

  

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

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