Blazor 0.6.0 "салфетки" Flurl-совместимость?

blazor flurl httpclientfactory

Вопрос

После обновления Blazor с 0.5.1 (с рабочим Flurl) до 0.6.0, вызовы через flurl выдают исключение:

WASM: [Flurl.Http.FlurlHttpException] Call failed. Cannot invoke method 
because it was wiped. See stack trace for details.

Проект создает HttpClientFactory, который получает HttpClient Blazor для использования Flurl:

Создайте FlurlClient с помощью HttpClient Blazor (http) с помощью HttpClientFactoryForBlazor:

IFlurlClient c = new FlurlClient() { Settings = new Flurl.Http.Configuration.ClientFlurlHttpSettings { HttpClientFactory = new HttpClientFactoryForBlazor(http) }};

Используйте FlurlClient (c), например, с помощью метода расширения Flurl «IFlurlRequest.WithClient (c);»

private class HttpClientFactoryForBlazor : Flurl.Http.Configuration.IHttpClientFactory
{
    private readonly HttpClient httpClient;

    public HttpClientFactoryForBlazor(HttpClient httpClient)
    {
        this.httpClient = httpClient;
    }

    public virtual HttpClient CreateHttpClient(HttpMessageHandler handler)
    {
        return this.httpClient;
    }
}

Таким образом, похоже, что этот подход больше не работает.

Кто-нибудь знает, как заставить Flurl работать с Blazor 0.6.0?

Call-Stack:

WASM: [Flurl.Http.FlurlHttpException] Call failed. Cannot invoke method because it was wiped. See stack trace for details. GET http://srv01.servicegrid.eu:4455/API/Status?forceLoadDbs=False blazor.webassembly.js:1:32098
WASM:   at Flurl.Http.FlurlRequest.HandleExceptionAsync (Flurl.Http.HttpCall call, System.Exception ex, System.Threading.CancellationToken token) <0x26945b8 + 0x001c2> in <c38761af4558433f81b1691eb86a1548>:0 blazor.webassembly.js:1:32098
WASM:   at Flurl.Http.FlurlRequest.SendAsync (System.Net.Http.HttpMethod verb, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken, System.Net.Http.HttpCompletionOption completionOption) <0x2665d30 + 0x005e6> in <c38761af4558433f81b1691eb86a1548>:0 blazor.webassembly.js:1:32098
WASM:   at Flurl.Http.FlurlRequest.SendAsync (System.Net.Http.HttpMethod verb, System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken, System.Net.Http.HttpCompletionOption completionOption) <0x2665d30 + 0x0079a> in <c38761af4558433f81b1691eb86a1548>:0 blazor.webassembly.js:1:32098
WASM:   at Flurl.Http.HttpResponseMessageExtensions.ReceiveJson[T] (System.Threading.Tasks.Task`1[TResult] response) <0x26a2180 + 0x000d6> in <c38761af4558433f81b1691eb86a1548>:0 blazor.webassembly.js:1:32098
WASM:   at DotNetFabrik.FlurlExtensions.FlurlRequestExtensions.HandleWebApiExceptions[T] (System.Threading.Tasks.Task`1[TResult] task) <0x26a43f8 + 0x000e2> in <8c1e6df9d3f545cd831ff49915df2d85>:0 blazor.webassembly.js:1:32098
WASM:   at DotNetFabrik.FlurlExtensions.FlurlRequestExtensions.HandleWebApiExceptions[T] (System.Threading.Tasks.Task`1[TResult] task) <0x26a43f8 + 0x00264> in <8c1e6df9d3f545cd831ff49915df2d85>:0 blazor.webassembly.js:1:32098
WASM:   at BlazorCoreDMSTools.CommunicationService.CommunicationService.SetTokenAsync (System.String token, System.String database, System.String serverUri) <0x260dc60 + 0x00d9e> in <cb925648b50340888772566fbaeac465>:0 

Принятый ответ

Как раз для некоторого фона, команда Blazor находится в процессе значительного сокращения отпечатка приложения и прибегает к некоторым необычным мерам для этого. В двух словах они уменьшили его примерно на 20% путем «вытирания» HttpClientHandler .

wipe означает «заменить указанные тела метода одной командой броска». Выполнение этого (а не фактического удаления метода целиком) означает, что сборка сохраняет полностью стандартную поверхность API, и если вы попытаетесь использовать один из протертых методов, вы получите легко понятную трассировку стека исключений, которая сообщит вам, какие вытирали метод, который вы пытаетесь вызвать.

Это то, с чем вы столкнулись: Blazor все еще знает HttpClientHandler для целей компиляции, но будет генерировать исключение во время выполнения, если вы (или в этом случае совместимая библиотека) попытаетесь его использовать.

Но HttpClient должен обернуть некоторую реализацию HttpMessageHandler Blazor имеет свой собственный: BrowserHttpMessageHandler . И Flurl предоставляет простой способ обменять это через HttpClientFactory . Но вам не нужно передавать экземпляр HttpClient или реализовывать CreateHttpClient . Вместо этого наследуйте DefaultHttpClientFactory и просто переопределите CreateMessageHandler :

private class HttpClientFactoryForBlazor : DefaultHttpClientFactory
{
    public override HttpMessageHandler CreateMessageHandler()
    {
        return new BrowserHttpMessageHandler();
    }
}

Я бы также рекомендовал зарегистрировать это один раз в глобальном масштабе при запуске приложения, а не каждый раз, когда вы создаете FlurlClient :

FlurlHttp.Configure(settings =>
{
    settings.HttpClientFactory = new HttpClientFactoryForBlazor();
});

Следует также отметить, что Blazor все еще экспериментален и что BrowserHttpMessageHandler может быть устаревшим в будущей версии , поэтому ожидайте, что это может быть просто временным BrowserHttpMessageHandler .



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему