gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 12:55:18 25 4
gpt4 key购买 nike

我有一个引用 .NET Core 类库的 MVC 核心应用程序。所有的数据访问和业务逻辑都在类库中。我怎样才能从类库访问经过身份验证的用户?

在过去使用 .NET Framework 时,您可以使用

string UserName = System.Web.HttpContext.Current.User.Identity.Name

从类库中的方法中获取用户名。在 .NET Core 中,HttpContext 似乎不再具有 CurrentUser 属性。

这是一个简单的用例。假设我有一个数据实体和服务,可以在将实体保存到数据库之前用日期和用户名“标记”实体。

这些将在外部类库中:

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 Controller 中,我将有一个调用该服务的后期操作:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(MyEntity model)
{
await service.Create(model);
return RedirectToAction("Index")
}

我想要一种方法来替换 Auditor.Stamp 中的那一行,因为 .NET Core 中显然没有 HttpContext.Current

This post给出一个如何在 Core 中获取用户名的例子:

public class UserResolverService  
{
private readonly IHttpContextAccessor _context;
public UserResolverService(IHttpContextAccessor context)
{
_context = context;
}

public string GetUser()
{
return await _context.HttpContext.User?.Identity?.Name;
}
}

但我遇到了同一问题的另一个版本:如何从类库中获取 IHttpContextAccessor 对象?

我的大部分搜索结果只涉及如何从 MVC Controller 方法中获取用户名的问题。过去,我已将一个 User 对象传递给每个服务的每个方法,但那是很多额外的输入——我宁愿有一些我可以输入一次的东西(也许在 Startup 中?)然后忘记它。

我确实想要一些我可以为单元测试模拟的东西,但老实说,我认为将 System.Web.HttpContext.Current.User.Identity.Name 包装在可以模拟的东西中非常容易。

最佳答案

此版本中仍然存在相同的灵 active 。

注入(inject) IHttpContextAccessor,您就可以访问所需的内容。

重构静态Auditor使其更可注入(inject)

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();
}
}

您实际上也应该注入(inject) 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.
}

然后就可以在Start up from the root project中调用了

public void ConfigureServices(IServiceCollection services) {

//...

services.AddMyLibrary();

//...
}

通过这些抽象和使用 DI 应用程序部件被解耦并且可以单独测试。

关于c# - 如何从 .Net Core 中的单独类库获取经过身份验证的用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50512770/

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