将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的扩展方法“ IFlurlRequest.WithClient(c);”来使用FlurlClient(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
答案 0 :(得分:9)
就某些背景而言,Blazor团队正在大幅减少应用程序的占用空间,并诉诸unusual measures这样做。简而言之,他们通过“擦除” HttpClientHandler
将其减少了约20%。
wipe 的意思是“一次扔掉指定的方法主体 指令”。这样做(而不是实际删除方法 完全)表示该程序集保留了完全标准的API 表面,如果您尝试使用其中一种擦拭方法,则会得到 易于理解的异常堆栈跟踪,告诉您擦除了哪些 您尝试调用的方法。
这是您所反对的:Blazor仍然知道HttpClientHandler
用于编译,但是如果您(或在本例中为兼容的库)尝试使用它,则会抛出运行时异常。 / p>
但是HttpClient
必须包装HttpMessageHandler
的 some 实现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
may be deprecated in a future release,因此希望这只是暂时的解决方法。
答案 1 :(得分:0)
当前在我的3.0预览版5中,BrowserHttpMessageHandler
不再存在。这是我目前的解决方法,只需不使用任何HttpMessageHandler
。据我所知,我还没有遇到任何问题,但是我不确定在所有使用情况下:
class BlazorHttpClientFactory : DefaultHttpClientFactory
{
public override HttpClient CreateHttpClient(HttpMessageHandler handler)
{
return new HttpClient();
}
public override HttpMessageHandler CreateMessageHandler()
{
return null;
}
}