realist
realist

Reputation: 2385

Access HttpContextAccessor from Helper Class in .net core web api

I want to access JwtHelper from ExceptionHelper. But problem is ExceptionHelper must be static. And so, we can't create constructor and not access jwtHelper Method. How can I achieve access jwHelper from 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;
        }
    }

Upvotes: 0

Views: 2236

Answers (2)

cl0ud
cl0ud

Reputation: 1614

If I were you I would register JwtHelper with a Interface known as IJwtHelper. It would look like this then

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

In my startup.cs class I would then do

 services.AddSingleton<IJwtHelper, JwtHelper>();

And then when you want to access your helper I would inject IJwtHelper

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

where _jwtHelper is field of type IJwtHelper.

You will then be able to use GetValueFromToken quite fine anywhere you inject IJwtHelper

UPDATE

Your problem is that ExceptionHandler is Static , implement an interface and add it to container

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

Then

 services.AddSingleton<IExceptionHelper, ExceptionHelper>();

Now You will be able to inject it into your Configure method like so

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

}

If you follow me advice above from my initial response and my update everything should be fine and registered nicely in your container :)

Upvotes: 1

Sean
Sean

Reputation: 1557

You'll have to instantiate the JwtHelper class in order to access the instance variable (httpContextAccessor) from another class. Static methods, like GetValueFromToken, cannot access instance variables.

Upvotes: 0

Related Questions