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

我有一个引用 .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 显然没有。


慕码人8056858
浏览 251回答 1
1回答

慕码人2483693

在这个版本中仍然存在同样的灵活性。注入IHttpContextAccessor并且您可以访问您需要的内容。重构静态Auditor以使其更具可注入性public interface IAuditor {&nbsp; &nbsp; IAuditable Stamp(IAuditable model);}public class Auditor : IAuditor {&nbsp; &nbsp; private readonly IHttpContextAccessor accessor;&nbsp; &nbsp; public Auditor(IHttpContextAccessor accessor) {&nbsp; &nbsp; &nbsp; &nbsp; this.accessor = accessor;&nbsp; &nbsp; }&nbsp; &nbsp; public IAuditable Stamp(IAuditable model){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; model.CreateDate = DateTime.UtcNow;&nbsp; &nbsp; &nbsp; &nbsp; model.CreatedBy = accessor.HttpContext.User?.Identity?.Name;&nbsp; &nbsp; &nbsp; &nbsp; return model;&nbsp; &nbsp; }}然后服务将依赖于新的抽象public interface IMyService : IDisposable {&nbsp; &nbsp; Task<int> Create(MyEntity model);}public sealed class MyService : IMyService {&nbsp; &nbsp; MyDb db = new MyDb();&nbsp; &nbsp; private readonly IAuditor auditor;&nbsp; &nbsp; public MyService(IAuditor auditor) {&nbsp; &nbsp; &nbsp; &nbsp; this.auditor = auditor;&nbsp; &nbsp; }&nbsp; &nbsp; public async Task<int> Create(MyEntity model) {&nbsp; &nbsp; &nbsp; &nbsp; auditor.Stamp(model);&nbsp; &nbsp; &nbsp; &nbsp; db.MyEntities.Add(model);&nbsp; &nbsp; &nbsp; &nbsp; return await db.SaveAsync();&nbsp; &nbsp; }&nbsp; &nbsp; public void Dispose() {&nbsp; &nbsp; &nbsp; &nbsp; db.Dispose();&nbsp; &nbsp; }}您确实也应该注入 ,MyDb但这超出了当前问题的范围。最后,您将库配置为能够在启动期间设置服务public static IServiceCollection AddMyLibrary(this IServiceCollection services) {&nbsp; &nbsp; services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();&nbsp; &nbsp; services.AddSingleton<IAuditor, Auditor>();&nbsp;&nbsp;&nbsp; &nbsp; services.AddScoped<IMyService, MyService>();&nbsp; &nbsp; //...add other services as needed&nbsp; &nbsp; return services.&nbsp;&nbsp;}然后你可以在从根项目启动时调用它public void ConfigureServices(IServiceCollection services) {&nbsp; &nbsp; //...&nbsp; &nbsp; services.AddMyLibrary();&nbsp; &nbsp; //...}通过这些抽象和使用 DI 应用程序部分是解耦的,可以单独测试。
打开App,查看更多内容
随时随地看视频慕课网APP