HttpContext is null in a hosted service in .NET Core web app

119 Views Asked by At

I developed a .NET Core web application.

That web application should periodically get information from some controller of the same web application. To accomplish it, I have created a class that implements IHostedService interface. Then, in Program.cs file, I added the service with:

services.AddHostedService<EventPollingService>()

By doing this, I realized that the hosted service is instantiated as a singleton object.

On the other hand, I pass IHttpContextAccessor accessor in the hosted service constructor to get it available using DI.

The problem is that, in order to call a controller in the same app, I need to pass an absolute URL, so in the hosted service constructor I am doing this:

_baseUrl = accessor.HttpContext?.Request.BaseUrl() ?? string.Empty;

The problem is that in this case HttpContext is null.

On the other hand, inside the hosted service I need to do some insertions into a database, so I think I will have similar problems getting the DbContext instance since it is added as scoped service.

How can I do this? Can you recommend another approach in case this one is not technically possible?

1

There are 1 best solutions below

0
Yazan Ati On

Hosted services has no HttpContext because they do not directly receive HTTP requests. If you want to get the URLs that hosted service is running on, use the ApplicationStarted trigger in your hosted service to access the server features. The code below explains what i mean:

public class EventPollingService : IHostedService
{
    private readonly IServer _server;
    private readonly IHostApplicationLifetime _hostApplicationLifetime;
    private ICollection<string> _urls;

    public EventPollingService(IServer server, IHostApplicationLifetime hostApplicationLifetime)
    {
        _server = server;
        _hostApplicationLifetime = hostApplicationLifetime;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _hostApplicationLifetime.ApplicationStarted.Register(() =>
        {
            _urls = _server.Features.Get<IServerAddressesFeature>()?.Addresses ?? null;
        });

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}