gpt4 book ai didi

c# - IHttpContextAccessor.HttpContext.User.Identity 显示 CurrentUserService 服务中的所有空属性

转载 作者:行者123 更新时间:2023-12-03 21:16:52 32 4
gpt4 key购买 nike

我正在尝试使用 Jason Taylor's Clean Architecture Template ,这个模板使用NSwag自动创建了一个TypeScript Client(Angular),但是我不需要创建TS客户端,所以我的主要目标是用Razor Pages替换它。我已经能够做到这一点,但当 CurrentUserService 被实例化时,我遇到了问题,它应该在这一行中设置 UserId:

UserId = httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);

这是完整的 CurrentUserService:
using CleanREC0.Application.Common.Interfaces;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;

namespace CleanREC0.WebUI.Services
{
public class CurrentUserService : ICurrentUserService
{
public CurrentUserService(IHttpContextAccessor httpContextAccessor)
{
UserId = httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
}

public string UserId { get; }
}
}

第一次甚至 HttpContext 为空,这很好,因为一切都在初始化,但随后的调用总是在所有 httpContextAccessor.HttpContext.User.Identity 属性上返回 null,用户显示了一个身份,但它的所有属性和声明都是null 或 Yield no results,即使用户正确登录。

这是我对模板所做的事情的列表:
  • 摆脱了 NSwag 和所有 TypeScript 相关内容
  • 摆脱了 IdentityServer
  • 为 IdentityDbContext 替换了 ApiAuthorizationDbContext

  • 这是我的 StartUp 类(class):
    public class Startup
    {
    public Startup(IConfiguration configuration, IWebHostEnvironment environment)
    {
    Configuration = configuration;
    Environment = environment;
    }

    public IConfiguration Configuration { get; }
    public IWebHostEnvironment Environment { get; }

    public void ConfigureServices(IServiceCollection services)
    {
    services.AddApplication();
    services.AddInfrastructure(Configuration, Environment);

    services.AddScoped<ICurrentUserService, CurrentUserService>();

    services.AddHttpContextAccessor();
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>(); //I have added this line on as suggested on other post, but made no difference.


    services.AddHealthChecks()
    .AddDbContextCheck<ApplicationDbContext>();

    services.AddRazorPages()
    .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<IApplicationDbContext>());
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    app.UseDatabaseErrorPage();
    }
    else
    {
    app.UseExceptionHandler("/Error");
    app.UseHsts();
    }

    app.UseCustomExceptionHandler();
    app.UseHealthChecks("/health");
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
    endpoints.MapRazorPages();
    });
    }
    }

    这是从 ConfigureServices 调用的 AddApplication:
    public static IServiceCollection AddApplication(this IServiceCollection services)
    {
    services.AddAutoMapper(Assembly.GetExecutingAssembly());
    services.AddMediatR(Assembly.GetExecutingAssembly());
    services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPerformanceBehaviour<,>));
    services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestValidationBehavior<,>));

    return services;
    }

    以及也在那里被调用的 AddInfrastructure:
    public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration, IWebHostEnvironment environment)
    {
    services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(
    configuration.GetConnectionString("DefaultConnection"),
    b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)));

    services.AddScoped<IApplicationDbContext>(provider => provider.GetService<ApplicationDbContext>());

    services.AddDefaultIdentity<ApplicationUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

    if (environment.IsEnvironment("Test"))
    {

    }
    else
    {
    services.AddTransient<IDateTime, DateTimeService>();
    services.AddTransient<IIdentityService, IdentityService>();
    services.AddTransient<ICsvFileBuilder, CsvFileBuilder>();
    }

    services.AddAuthentication();

    return services;
    }

    其他一切似乎都运行良好。在 Razor 页面级别,用户变量及其身份包含所有预期信息和声明。

    我确定我遗漏了一些东西,有人可以指出我正确的方向吗?

    最佳答案

    LinkedListT 在评论中的链接让我找到了正确的方向。

    该链接指向一个解释这一点的答案:

    under the ASP.NET MVC framework, the HttpContext (and therefore HttpContext.Session) is not set when the controller class is contructed as you might expect, but it set ("injected") later by the ControllerBuilder class.



    我正在使用的模板附带的 CurrentUserService 类尝试读取构造函数中的用户声明,因此我将代码移动到属性的 getter,它会在实际使用该属性时执行,然后所有声明和属性都是人口稠密。

    我的新 CurrentUserService 如下所示:
    using CleanREC0.Application.Common.Interfaces;
    using Microsoft.AspNetCore.Http;
    using System.Security.Claims;

    namespace CleanREC0.WebUI.Services
    {
    public class CurrentUserService : ICurrentUserService
    {
    private IHttpContextAccessor _httpContextAccessor;

    public CurrentUserService(IHttpContextAccessor httpContextAccessor)
    {
    _httpContextAccessor = httpContextAccessor;
    }

    public string UserId { get { return _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier); }}
    }
    }

    关于c# - IHttpContextAccessor.HttpContext.User.Identity 显示 CurrentUserService 服务中的所有空属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59793111/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com