【发布时间】:2020-10-23 22:49:00
【问题描述】:
编辑:10-27-20
我正在重写这篇文章,因为经过一个多星期后,我现在对问题和解决方案都有了更好的理解。
第一个问题:
暴击:Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
未处理的异常呈现组件:找不到适合类型“System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler”的构造函数。确保类型是具体的,并且为公共构造函数的所有参数注册了服务。
System.InvalidOperationException:找不到适合类型“System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler”的构造函数。确保类型是具体的,并且为公共构造函数的所有参数注册了服务。
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ResultCache 生命周期,System.Type serviceType,System.Type implementationType,Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSiteChain)在:0
...
最初我虽然这与 Azure 相关联,但事实并非如此。它与在 Release 而非 Debug 下编译我的项目有关。
下面的旧选择 - 请忽略并跳转到答案 =>
当我在我的计算机上测试我的 Blazor 应用程序时,我没有收到任何错误,但是一旦我发布到我的 Azure 应用程序服务,我就会收到很长的错误集...
暴击:Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未处理的异常呈现组件:找不到适合类型“System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler”的构造函数。确保类型是具体的,并且为公共构造函数的所有参数注册了服务。 System.InvalidOperationException:找不到适合类型“System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler”的构造函数。确保类型是具体的,并且为公共构造函数的所有参数注册了服务。 在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ResultCache 生命周期,System.Type serviceType,System.Type implementationType,Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain callSiteChain)在:0
...
我了解注入系统正在寻找 JwtSecurityTokenHandler,但无法找到。我对没有 Web UI 的旧 MVC API 使用相同的配置,它工作得很好,就像我说它在我的本地系统上工作,但在 Azure 上我得到一个错误。我知道我遗漏了一些简单的东西,但我找不到。
感谢您查看这个。
public void ConfigureServices(IServiceCollection services)
{
//Other DI Here
services.AddScoped<JwtSecurityTokenHandler>();
services.AddAuthentication(options =>
{
// Identity made Cookie authentication the default.
// However, we want JWT Bearer Auth to be the default.
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
// Configure JWT Bearer Auth to expect our security key
cfg.TokenValidationParameters =
new TokenValidationParameters
{
LifetimeValidator = (before, expires, token, param) =>
{
return expires > DateTime.UtcNow;
},
ValidateAudience = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSecretKey"]))
};
});
services.AddScoped<IInventoryAdjustmentRepository, InventoryAdjustmentRepository>();
services.AddScoped<IEmployeeDataRepository, EmployeeDataRepository>();
services.AddScoped<IPartDataRepository, PartDataRepository>();
services.AddScoped<IInventoryScheduleRepository, InventoryScheduleRepository>();
}
编辑:客户端配置
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddScoped<JwtSecurityTokenHandler>();
builder.Services.AddScoped<ApiAuthStateProvider, ApiAuthStateProvider>();
builder.Services.AddScoped<AuthenticationStateProvider>(p => p.GetService<ApiAuthStateProvider>());
builder.Services.AddTransient<IAuthenticationContract, UserServices>();
builder.Services.AddTransient<IEmployeeDataContract, EmployeeService>();
builder.Services.AddTransient<IPartRepository, PartRepository>();
builder.Services.AddTransient<IInventorySchedule, InventorySchedule>();
builder.Services.AddSingleton<IBrowserLocalStorage, BrowserLocalStorage>();
builder.Services.AddSingleton<IBrowserSessionStorage, BrowserSessionStorage>();
builder.Services.AddAuthorizationCore();
builder.Services.AddSyncfusionBlazor();
//Syncfusion.Licensing...
builder.RootComponents.Add<App>("app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddApiAuthorization();
await builder.Build().RunAsync();
【问题讨论】:
-
您已经按照this question and answer 建议的方式进行操作了……所以我唯一可以贡献的就是指出用户曾对其他问题的评论……他说:“你不应该注入它。
JwtSecurityTokenHandler有一个无参数的构造函数,不是一次性的,并且具有与其父级相同的生命周期。只是new它“......我无法提供任何想法或理由为什么它在本地工作但不在 Azure 中。 -
感谢您的建议。我也读到了,对反应感到困惑。确实,您使用新令牌创建了令牌,但这个问题似乎出在 DI 中,而不是创建令牌。话虽如此,我认为问题出在客户端应用程序上,而不是服务器 API 上。我可以使用邮递员获取令牌并访问服务器上的授权 API 端点。我正在调查客户端的 DI。这是我第一次使用 Blazor Web 程序集,开始时我选择了“一体化”模板。我将很快用我的客户端配置编辑我的帖子,看看这是否是我的问题。
标签: c# dependency-injection blazor