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

После обновления 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 Блазора для использования Flurl:

Создайте FlurlClient с помощью HttpClient (http) Blazor, используя 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 

1 ответ

Решение

Просто для справки, команда 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 может быть устаревшим в будущем выпуске, так что ожидайте, что это может быть только временное решение.

В настоящее время в моем 3.0 превью 5, BrowserHttpMessageHandler там больше нет Вот мое текущее исправление, просто не используя какие-либо HttpMessageHandler, Насколько я знаю, со мной еще не возникает никаких проблем, но я не уверен во всех случаях использования:

class BlazorHttpClientFactory : DefaultHttpClientFactory
{

    public override HttpClient CreateHttpClient(HttpMessageHandler handler)
    {
        return new HttpClient();
    }

    public override HttpMessageHandler CreateMessageHandler()
    {
        return null;
    }

}
Другие вопросы по тегам