После обновления 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
.