最近,我将我的项目从Asp.Net Core 3.0升级到了最新的构建Asp.Net Core 3.1.0 preview 3。
我的项目正在客户机中运行Blazor,我还拦截管道,将一个Jwt添加到使用扩展JwtTokenHeaderHandler的DelegatingHandler发送回服务器的每个请求的头上。
我在我的startup.cs blazor.client项目中添加了以下内容:
services.AddSingleton<HttpClient>(s =>
{
// Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it.
var uriHelper = s.GetRequiredService<NavigationManager>();
var myHandler = s.GetRequiredService<JwtTokenHeaderHandler>();
myHandler.InnerHandler = new WebAssemblyHttpMessageHandler();
return new HttpClient(myHandler)
{
BaseAddress = new Uri(uriHelper.BaseUri)
};
}); 但是,自从升级之后,WebAssemblyHttpMessageHandler()似乎不再可用了?
我找不到任何关于如何修复这种方法的文档。
有人能告诉我如何纠正这个问题吗?
基于Aqua答案的更新
将以下代码添加到我的Startup.cs之后;
services.AddTransient(p =>
{
var wasmHttpMessageHandlerType = Assembly.Load("WebAssembly.Net.Http")
.GetType("WebAssembly.Net.Http.HttpClient.WasmHttpMessageHandler");
var constructor = wasmHttpMessageHandlerType.GetConstructor(Array.Empty<Type>());
return constructor.Invoke(Array.Empty<object>()) as HttpMessageHandler;
})
.AddTransient<JwtTokenHeaderHandler>();从我的Authorized文件中调用一个.razor获取端点;
var response = await Http.GetAsync<ContactTypeOutputModel[]>("ContactTypes/all");(上面只是使用扩展方法的类型包装服务响应);
public static async Task<ServiceResponse<T>> GetAsync<T>(
this HttpClient httpClient, string url)
{
var response = await httpClient.GetAsync(url);
return await BuildResponse<T>(response);
}我还能拿到401的服务吗?而没有输出日志来表示服务正在被使用?
public class JwtTokenHeaderHandler : DelegatingHandler
{
private readonly IAppLocalStorageService _localStorage;
private readonly ILogger<JwtTokenHeaderHandler> _logger;
private readonly HttpMessageHandler _innerHandler;
private readonly MethodInfo _method;
public JwtTokenHeaderHandler(IAppLocalStorageService localStorage, HttpMessageHandler innerHandler, ILogger<JwtTokenHeaderHandler> logger)
{
_localStorage = localStorage;
_logger = logger;
_innerHandler = innerHandler;
var type = innerHandler.GetType();
_method = type.GetMethod("SendAsync", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod) ?? throw new InvalidOperationException("Cannot get SendAsync method");
WebAssemblyHttpMessageHandlerOptions.DefaultCredentials = FetchCredentialsOption.Include;
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
_logger.LogDebug("Adding Jwt to Header from JwtTokenHeaderHandler: SendAsync");
_logger.LogDebug($"Does header contain 'bearer' token: {!request.Headers.Contains("bearer")}");
if (!request.Headers.Contains("bearer"))
{
_logger.LogDebug("Adding Bearer Token to Header");
var savedToken = await _localStorage.GetTokenAsync();
_logger.LogDebug($"Saved Token is : {savedToken}");
if (!string.IsNullOrWhiteSpace(savedToken))
{
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", savedToken);
}
}
//return await base.SendAsync(request, cancellationToken);
return await (_method.Invoke(_innerHandler, new object[] { request, cancellationToken }) as Task<HttpResponseMessage>);
}
}知道为什么这个没被击中吗?
发布于 2019-11-26 13:37:58
由于无法向WebAssembly.Net.Http.添加依赖项,WebAssemblyHttpMessageHandler已被Mono的WasmHttpMessageHandler替换为了为blazor创建一个DependencyHandler,我做了一个小黑客:
public class OidcDelegationHandler : DelegatingHandler
{
private readonly IUserStore _userStore;
private readonly HttpMessageHandler _innerHanler;
private readonly MethodInfo _method;
public OidcDelegationHandler(IUserStore userStore, HttpMessageHandler innerHanler)
{
_userStore = userStore ?? throw new ArgumentNullException(nameof(userStore));
_innerHanler = innerHanler ?? throw new ArgumentNullException(nameof(innerHanler));
var type = innerHanler.GetType();
_method = type.GetMethod("SendAsync", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod) ?? throw new InvalidOperationException("Cannot get SendAsync method");
WebAssemblyHttpMessageHandlerOptions.DefaultCredentials = FetchCredentialsOption.Include;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Authorization = new AuthenticationHeaderValue(_userStore.AuthenticationScheme, _userStore.AccessToken);
return _method.Invoke(_innerHanler, new object[] { request, cancellationToken }) as Task<HttpResponseMessage>;
}
}在DI中将其设置为:
return services
.AddTransient(p =>
{
var wasmHttpMessageHandlerType = Assembly.Load("WebAssembly.Net.Http")
.GetType("WebAssembly.Net.Http.HttpClient.WasmHttpMessageHandler");
var constructor = wasmHttpMessageHandlerType.GetConstructor(Array.Empty<Type>());
return constructor.Invoke(Array.Empty<object>()) as HttpMessageHandler;
})完整的代码是这里
https://stackoverflow.com/questions/59051760
复制相似问题