为了账号安全,请及时绑定邮箱和手机立即绑定

如何从 .Net Core 中的单独类库中获取经过身份验证的用户

如何从 .Net Core 中的单独类库中获取经过身份验证的用户

C#
慕码人8056858 2021-06-28 13:51:00
我有一个引用 .NET Core 类库的 MVC 核心应用程序。所有的数据访问和业务逻辑都在类库中。如何从类库访问经过身份验证的用户?过去使用 .NET Framework 您可以使用string UserName = System.Web.HttpContext.Current.User.Identity.Name从类库中的方法内部获取用户名。在 .NET Core 中,似乎HttpContext不再具有CurrentorUser属性。这是一个简单的用例。假设我有一个数据实体和服务,它在将实体保存到数据库之前用日期和用户名“标记”实体。这些将在外部类库中:public interface IAuditable{    DateTime CreateDate{get;set;}    string UserName{get;set;}}public class MyEntity:IAuditable{    public int ID{get;set;}    public string Name{get;set;}    public string Information{get;set;}}public static class Auditor{    public static IAuditable Stamp(IAuditable model){                    model.CreateDate=DateTime.UtcNow;        model.CreatedBy=System.Web.HttpContext.Current.User.Identity.Name;        return model;    }}public sealed class MyService:IDisposable{    MyDb db=new MyDb();    public async Task<int> Create(MyEntity model){        Auditor.Stamp(model);        db.MyEntities.Add(model);        return await db.SaveAsync();    }    public void Dispose(){        db.Dispose();    }}然后在我的 MVC 控制器中,我有一个调用服务的 post 操作:[HttpPost][ValidateAntiForgeryToken]public async Task<IActionResult> Create(MyEntity model){    await service.Create(model);    return RedirectToAction("Index")}我想要一种方法来替换该行,Auditor.Stamp因为HttpContext.Current.NET Core 显然没有。
查看完整描述

1 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

在这个版本中仍然存在同样的灵活性。


注入IHttpContextAccessor并且您可以访问您需要的内容。


重构静态Auditor以使其更具可注入性


public interface IAuditor {

    IAuditable Stamp(IAuditable model);

}


public class Auditor : IAuditor {

    private readonly IHttpContextAccessor accessor;


    public Auditor(IHttpContextAccessor accessor) {

        this.accessor = accessor;

    }


    public IAuditable Stamp(IAuditable model){            

        model.CreateDate = DateTime.UtcNow;

        model.CreatedBy = accessor.HttpContext.User?.Identity?.Name;

        return model;

    }

}

然后服务将依赖于新的抽象


public interface IMyService : IDisposable {

    Task<int> Create(MyEntity model);

}


public sealed class MyService : IMyService {

    MyDb db = new MyDb();

    private readonly IAuditor auditor;


    public MyService(IAuditor auditor) {

        this.auditor = auditor;

    }


    public async Task<int> Create(MyEntity model) {

        auditor.Stamp(model);

        db.MyEntities.Add(model);

        return await db.SaveAsync();

    }


    public void Dispose() {

        db.Dispose();

    }

}

您确实也应该注入 ,MyDb但这超出了当前问题的范围。


最后,您将库配置为能够在启动期间设置服务


public static IServiceCollection AddMyLibrary(this IServiceCollection services) {


    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    services.AddSingleton<IAuditor, Auditor>();  

    services.AddScoped<IMyService, MyService>();


    //...add other services as needed


    return services.  

}

然后你可以在从根项目启动时调用它


public void ConfigureServices(IServiceCollection services) {


    //...


    services.AddMyLibrary();


    //...

}

通过这些抽象和使用 DI 应用程序部分是解耦的,可以单独测试。


查看完整回答
反对 回复 2021-07-03
  • 1 回答
  • 0 关注
  • 245 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信