c# - IHttpContextAccessor注入(inject)后为null

标签 c# asp.net-core httpcontext

我目前正在开发一个系统,该系统需要加载来自不同网站设​​置的请求域(例如,默认语言ID),然后将其用于该应用程序的其余部分。这些设置存储在类WebsiteSettings中,并在需要时注入到应用程序的其余部分中。

我尝试的第一个选项是通过在HttpContext方法中执行以下操作来注册服务以访问ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
    //Register other services

    services.TryAddScoped<IHttpContextAccessor, HttpContextAccessor>();
    services.TryAddScoped<WebsiteSettingsFiller>();
    services.TryAddScoped(typeof(WebsiteSettings), s =>
    {
        var settingFiller = s.GetService<WebsiteSettingsFiller>();
        return settingFiller.Create();
    });
}


接下来,在我的WebsiteSettingsFiller服务中,注入IHttpContextAccessor以及加载站点设置所需的其他一些服务。

public class WebsiteSettingsFiller
{
    protected readonly IRepository Database;
    private readonly IHttpContextAccessor _accessor;
    private readonly StartupSitePropertyService _sitePropertyService;
    private IQueryable<Site> AllSites => Database.All<Site>();
    private IQueryable<SiteLanguage> AllSiteLanguages => Database.All<SiteLanguage>();

    public WebsiteSettingsFiller(IRepository db, StartupSitePropertyService siteProperties, IHttpContextAccessor accessor)
    {
        Database = db;
        _accessor = accessor;
        _sitePropertyService = siteProperties;
    }

    public WebsiteSettings Create()
    {
        var domain = _accessor.HttpContext.Request.Host.Host; //null exception on this line
#if DEBUG
        domain = "www.somewebsite.com";
#endif
        var config = GetConfigByDomain(domain);
        return config;
    }

    private WebsiteSettings GetConfigByDomain(string domain)
    {
        var site = AllSites.OrderByDescending(s => s.Created).FirstOrDefault(t => t.Host == domain);
        if (site == null) return null;
        var languages = AllSiteLanguages.Where(sl => sl.SiteId == site.Id).ToList();
        //get more variables 
        return new WebsiteSettings
        {
            /* Set variables */
        }
    }
}


WebsiteSettings的示例注入:

public class RouteService : BaseService
{
    private IDictionary<int, string> _routeLanguages = null;
    private readonly WebsiteRedisService _websiteRedisService;

    public RouteService(IRepository db,
        WebsiteSettings settings,
        WebsiteRedisService websiteRedisService)
        : base(db, settings)
    {
        _websiteRedisService = websiteRedisService;
    }

    public async Task<IDictionary<int, string>> RouteLanguagesAsync()
    {
        return _routeLanguages ??
               (_routeLanguages = await _websiteRedisService.SiteLanguagesToAsync(Settings.SiteId));
    }
}


可悲的是,无论我尝试什么,HttpContext引用始终为null。有人知道我可以尝试解决什么吗?还是我只是以错误的方式来解决这个问题?任何建议,不胜感激!

最佳答案

IHttpContextAccessor应该作为Singleton注入。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}


在您的WebsiteSettingsFiller中,您可以在构造函数中获取HttpContext并将其分配给HttpContext字段。

public class WebsiteSettingsFiller
{
    //private readonly IHttpContextAccessor _accessor;
    private readonly HttpContext _context;

    public WebsiteSettingsFiller(IHttpContextAccessor accessor)
    {
        //_accessor = accessor;
        _context = accessor.HttpContext;
    }
}

关于c# - IHttpContextAccessor注入(inject)后为null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43227160/

相关文章:

c# - 如何在异常情况下读取 HttpActionExecutedContext 中的 JSON 正文

asp.net - HttpContext.Current.Items 重用吗?

c# - 添加到初始化的多维槽

c# - 为什么将 High chance 子句放在嵌套 If else 的前面会降低性能?

c# - 将 Kinect 深度读数映射到 Unity

c# - 使用 Entity Framework、Code First (POCO) 和 Code Contracts 运行更新数据库时出错

.net - EF Core 添加迁移构建失败

asp.net - 静态方法中的 HttpContext.Current NullReferenceException

visual-studio - 在 .NET Core 2.0 中查看项目属性时出错

c# - CreateParameter 上的 ASP.NET 5 vNext EF7 SQLite TypeLoadException