Blazor 0.6.0 "wipes" Flurl 兼容性?
Blazor 0.6.0 "wipes" Flurl-compatibility?
将 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) }};
例如通过 Flurl 的扩展方法使用 FlurlClient (c) "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 吗?
调用堆栈是:
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 团队正在显着减少应用程序的占用空间,并采取一些措施 unusual measures 来实现这一目标。简而言之,他们减少了大约 20% "wiping" HttpClientHandler
。
wipe means "replace specified method bodies with a single throw
instruction". Doing this (instead of actually removing the method
entirely) means that the assembly retains a completely standard API
surface, and if you try to use one of the wiped methods, you get an
easy-to-understand exception stack trace that tells you which wiped
method you're trying to call.
这就是您遇到的问题:Blazor 仍然知道 HttpClientHandler
用于编译目的,但如果您(或在本例中为兼容库)尝试使用它,则会抛出运行时异常.
但是 HttpClient
必须包装 一些 实现 HttpMessageHandler
Blazor 有它自己的:BrowserHttpMessageHandler
. And Flurl provides an easy way to swap this in via its 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
may be deprecated in a future release,因此预计这可能只是一个临时的解决方法。
目前在我的 3.0 预览版 5 中,BrowserHttpMessageHandler
已经不存在了。这是我目前的修复,只是不使用任何 HttpMessageHandler
。据我所知,我还没有遇到任何问题,但我不确定在所有用例中:
class BlazorHttpClientFactory : DefaultHttpClientFactory
{
public override HttpClient CreateHttpClient(HttpMessageHandler handler)
{
return new HttpClient();
}
public override HttpMessageHandler CreateMessageHandler()
{
return null;
}
}
将 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) }};
例如通过 Flurl 的扩展方法使用 FlurlClient (c) "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 吗?
调用堆栈是:
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 团队正在显着减少应用程序的占用空间,并采取一些措施 unusual measures 来实现这一目标。简而言之,他们减少了大约 20% "wiping" HttpClientHandler
。
wipe means "replace specified method bodies with a single throw instruction". Doing this (instead of actually removing the method entirely) means that the assembly retains a completely standard API surface, and if you try to use one of the wiped methods, you get an easy-to-understand exception stack trace that tells you which wiped method you're trying to call.
这就是您遇到的问题:Blazor 仍然知道 HttpClientHandler
用于编译目的,但如果您(或在本例中为兼容库)尝试使用它,则会抛出运行时异常.
但是 HttpClient
必须包装 一些 实现 HttpMessageHandler
Blazor 有它自己的:BrowserHttpMessageHandler
. And Flurl provides an easy way to swap this in via its 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
may be deprecated in a future release,因此预计这可能只是一个临时的解决方法。
目前在我的 3.0 预览版 5 中,BrowserHttpMessageHandler
已经不存在了。这是我目前的修复,只是不使用任何 HttpMessageHandler
。据我所知,我还没有遇到任何问题,但我不确定在所有用例中:
class BlazorHttpClientFactory : DefaultHttpClientFactory
{
public override HttpClient CreateHttpClient(HttpMessageHandler handler)
{
return new HttpClient();
}
public override HttpMessageHandler CreateMessageHandler()
{
return null;
}
}