Доступ к HttpContextAccessor из вспомогательного класса в .net core web api - PullRequest
0 голосов
/ 22 октября 2018

Я хочу получить доступ к JwtHelper из ExceptionHelper.Но проблема в том, что ExceptionHelper должен быть статическим.Итак, мы не можем создать конструктор и не получить доступ к методу jwtHelper.Как я могу получить доступ к jwHelper из ExcewptionHelper.

Startup.cs

 public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
    services.AddMvc();
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    services.AddDbContext<MyDbContext>();
    services.AddTransient<IUnitOfWork, UnitOfWork>();
}


public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
     app.UseExceptionHandler(builder => builder.Run(async context =>
     {
         var error = context.Features.Get<IExceptionHandlerFeature>();

         context.Response.AddApplicationError(error);
         await context.Response.WriteAsync(error.Error.Message);
     }));

    app.UseHttpsRedirection();
    app.UseMvc();
}

ExceptionHelper.cs

    public static class ExceptionHelper
    {
        public static async Task AddApplicationError(this HttpResponse response)
        {
            Log log = new Log();
            log.UserId = jwtHelper.GetValueFromToken(token, "UserId");??????
            //in this line I can't access jwtHelper.
        }
    }

JwtHelper.cs

 public class JwtHelper : IJwtHelper
    {
        private readonly IHttpContextAccessor httpContextAccessor;

        public JwtHelper(IHttpContextAccessor httpContextAccessor)
        {
            this.httpContextAccessor = httpContextAccessor;
        }

        public string GetValueFromToken(string stream, string propertyName)
        {
            var jwt = httpContextAccessor.HttpContext.Request.Headers["Authorization"];

            var handler = new JwtSecurityTokenHandler();
            var tokens = handler.ReadToken(stream.Replace("Bearer ", "")) as JwtSecurityToken;
            return tokens.Claims.FirstOrDefault(claim => claim.Type == propertyName).Value;
        }
    }

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

На вашем месте я бы зарегистрировал JwtHelper в интерфейсе, известном как IJwtHelper.Тогда это выглядело бы следующим образом:

public class JwtHelper : IJwtHelper
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public JwtHelper(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    public  string GetValueFromToken(string propertyName)
    {
        var jwt= httpContextAccessor.HttpContext.Request.Headers["Authorization"];
        // I can't access httpContextAccessor in this line.

        var handler = new JwtSecurityTokenHandler();
        var tokens = handler.ReadToken(jwt) as JwtSecurityToken;
        return tokens.Claims.FirstOrDefault(claim => claim.Type == propertyName).Value;
    }
}

public interface IJwtHelper
{
    string GetValueFromToken(string propertyName);
}

В моем классе startup.cs я бы тогда сделал

 services.AddSingleton<IJwtHelper, JwtHelper>();

И затем, когда вы захотите получить доступ к вашему помощнику, я добавлю IJwtHelper

  private IJwtHelper _jwtHelper;
  public SomeConstructerOnClass(IJwtHelper jwtHelper)
    {
        _jwtHelper = jwtHelper;
    }
 public void SomeMethod(string property) {
    var token = _jwtHelper.GetValueFromToken(property);
    //Do something with token
    }

где _jwtHelper - это поле типа IJwtHelper.

После этого вы сможете использовать GetValueFromToken довольно хорошо везде, где вводите IJwtHelper

ОБНОВЛЕНИЕ

Ваша проблема в том, что ExceptionHandler является статическим, реализует интерфейс и добавляет его в контейнер

  public class ExceptionHelper : IExceptionHelper
{
  private IJwtHelper _jwtHelper;
  public ExceptionHelper(IJwtHelper jwtHelper)
{
    _jwtHelper = jwtHelper;
}
    public async Task AddApplicationError(this HttpResponse response)
    {
        Log log = new Log();
        log.UserId = _jwtHelper.GetValueFromToken(token, "UserId");??????

    }
}
public interface IExceptionHelper
{
Task AddApplicationError( HttpResponse response);
 }

Затем

 services.AddSingleton<IExceptionHelper, ExceptionHelper>();

Теперь высможет внедрить его в ваш Configure метод, например, так:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IExceptionHelper exceptionHelper)
{
 app.UseExceptionHandler(builder => builder.Run(async context =>
 {
     var error = context.Features.Get<IExceptionHandlerFeature>();
     //Resolved and available!
     exceptionHelper.AddApplicationError(error);
     await context.Response.WriteAsync(error.Error.Message);
 }));

app.UseHttpsRedirection();
app.UseMvc();

}

Если вы последуете моему совету из моего первоначального ответа и моего обновления, все должно быть в порядке и зарегистрировано хорошов вашем контейнере:)

0 голосов
/ 22 октября 2018

Вам нужно будет создать экземпляр класса JwtHelper, чтобы получить доступ к переменной экземпляра (httpContextAccessor) из другого класса.Статические методы, такие как GetValueFromToken, не могут получить доступ к переменным экземпляра.

...