Blazor 0.6.0"擦拭"Flurl兼容性?

Sas*_*cha 7 flurl blazor 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.
Run Code Online (Sandbox Code Playgroud)

该项目创建了一个HttpClientFactory,它可以让Blazor的HttpClient被Flurl使用:

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

IFlurlClient c = new FlurlClient() { Settings = new Flurl.Http.Configuration.ClientFlurlHttpSettings { HttpClientFactory = new HttpClientFactoryForBlazor(http) }};
Run Code Online (Sandbox Code Playgroud)

使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,似乎这种方法不再起作用.

有谁知道如何使用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 
Run Code Online (Sandbox Code Playgroud)

Tod*_*ier 11

仅仅为了一些背景,Blazor团队正在大幅减少应用程序的占用空间,并采取一些不寻常的措施来实现这一目标.简而言之,他们通过"擦拭"将其减少了约20%HttpClientHandler.

擦除意味着"用单个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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我还建议在应用启动时全局注册一次,而不是每次创建一个FlurlClient:

FlurlHttp.Configure(settings =>
{
    settings.HttpClientFactory = new HttpClientFactoryForBlazor();
});
Run Code Online (Sandbox Code Playgroud)

还应该注意的是,Blazor仍然是实验性的,并且BrowserHttpMessageHandler可能在将来的版本中被弃用,所以期望这可能只是一个临时的解决方案.

  • 让人惊讶.我不确定维持一个不起作用的"API表面"是什么意思.我宁愿"目标"并在IDE中获得错误而不是这个.我真的希望blazor成功,但这样的事情是令人担忧的. (4认同)
  • “ BrowserHttpMessageHandler”“现在”(https://github.com/aspnet/AspNetCore/commit/ceb1c8e562562b2655622b571d2a9ad083806ad5)被命名为“ WebAssemblyHttpMessageHandler”。替换后仍可与上面的代码一起使用。 (3认同)