Después de actualizar Blazor de 0.5.1 (con Flurl en funcionamiento) a 0.6.0, las llamadas a través de flurl lanzan una excepción:
WASM: [Flurl.Http.FlurlHttpException] Call failed. Cannot invoke method
because it was wiped. See stack trace for details.
El proyecto crea un HttpClientFactory que obtiene HttpClient de Blazor para ser utilizado por Flurl:
Cree FlurlClient con HttpClient (http) de Blazor usando HttpClientFactoryForBlazor:
IFlurlClient c = new FlurlClient() { Settings = new Flurl.Http.Configuration.ClientFlurlHttpSettings { HttpClientFactory = new HttpClientFactoryForBlazor(http) }};
Utilice el FlurlClient (c), por ejemplo, mediante el método de extensión de 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;
}
}
Entonces, parece que este enfoque ya no funciona.
¿Alguien sabe cómo hacer que Flurl con Blazor 0.6.0 funcione?
Call-Stack es:
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
Solo por algunos antecedentes, el equipo de Blazor está en el proceso de reducir significativamente la huella de la aplicación y recurrir a algunas medidas inusuales para hacerlo. En pocas palabras, lo han reducido en aproximadamente un 20% al "borrar" HttpClientHandler
.
wipe significa "reemplazar los cuerpos de métodos especificados con una sola instrucción de lanzamiento". Hacer esto (en lugar de eliminar el método por completo) significa que el ensamblaje conserva una superficie API completamente estándar, y si intenta usar uno de los métodos eliminados, obtendrá un seguimiento de la pila de excepciones fácil de entender que le indica qué limpiado método al que intentas llamar.
Esto es con lo que te has topado: Blazor aún conoce HttpClientHandler
para fines de compilación, pero lanzará una excepción de tiempo de ejecución si tú (o en este caso una biblioteca compatible) intentas usarlo.
Pero HttpClient
debe envolver alguna implementación de HttpMessageHandler
Blazor tiene la suya: BrowserHttpMessageHandler
. Y Flurl proporciona una manera fácil de intercambiar esto a través de su HttpClientFactory
. Pero no necesita pasar una instancia de HttpClient
o implementar CreateHttpClient
. En su lugar, herede de DefaultHttpClientFactory
y simplemente anule CreateMessageHandler
:
private class HttpClientFactoryForBlazor : DefaultHttpClientFactory
{
public override HttpMessageHandler CreateMessageHandler()
{
return new BrowserHttpMessageHandler();
}
}
También recomiendo registrar esto una vez a nivel mundial en el inicio de la aplicación, en lugar de cada vez que crea un FlurlClient
:
FlurlHttp.Configure(settings =>
{
settings.HttpClientFactory = new HttpClientFactoryForBlazor();
});
También se debe tener en cuenta que Blazor aún es experimental y que BrowserHttpMessageHandler
puede quedar obsoleto en una versión futura , por lo que se espera que esto sea solo una solución temporal.
Actualmente en mi versión preliminar 3.0 3.0, BrowserHttpMessageHandler
ya no está allí. Aquí está mi solución actual simplemente no usando ningún HttpMessageHandler
. Hasta donde sé, todavía no me ocurre ningún problema, pero no estoy seguro en todos los casos de uso:
class BlazorHttpClientFactory : DefaultHttpClientFactory
{
public override HttpClient CreateHttpClient(HttpMessageHandler handler)
{
return new HttpClient();
}
public override HttpMessageHandler CreateMessageHandler()
{
return null;
}
}