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,它可以讓Blazor的HttpClient被Flurl使用:

使用HttpClientFactoryForBlazor使用Blazor的HttpClient(http)創建FlurlClient:

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;
    }
}

所以,似乎這種方法不再起作用。

有誰知道如何使用Blazor 0.6.0製作Flurl?

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團隊正在大幅減少應用程序的佔用空間,並採取一些不尋常的措施來實現這一目標。簡而言之,他們通過“擦拭” HttpClientHandler將其減少了約20%。

擦除意味著“用單個throw指令替換指定的方法體”。這樣做(而不是完全刪除方法)意味著程序集保留了完全標準的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可能在將來的版本中被棄用 ,所以期望這可能只是一個臨時的解決方法。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因