为啥 HttpContext.Current 为空?

Posted

技术标签:

【中文标题】为啥 HttpContext.Current 为空?【英文标题】:Why is HttpContext.Current null?为什么 HttpContext.Current 为空? 【发布时间】:2013-10-30 20:08:55 【问题描述】:

我有一个在所有应用程序中都使用的值;我在 application_start 中设置了这个

  void Application_Start(object sender, EventArgs e)
  
    Dictionary<int, IList<string>> Panels = new Dictionary<int, IList<string>>();
    List<clsPanelSetting> setting = clsPanelSettingFactory.GetAll();
    foreach (clsPanelSetting panel in setting)
    
        Panels.Add(panel.AdminId, new List<string>()  panel.Phone,panel.UserName,panel.Password);
    
    Application["Setting"] = Panels;

    SmsSchedule we = new SmsSchedule();
    we.Run();

  

在短信计划中

public class SmsSchedule : ISchedule

    public void Run()
               
        DateTimeOffset startTime = DateBuilder.FutureDate(2, IntervalUnit.Second);
        IJobDetail job = JobBuilder.Create<SmsJob>()
            .WithIdentity("job1")
            .Build();

        ITrigger trigger = TriggerBuilder.Create()
             .WithIdentity("trigger1")
             .StartAt(startTime)
             .WithSimpleSchedule(x => x.WithIntervalInSeconds(60).RepeatForever())
             .Build();

        ISchedulerFactory sf = new StdSchedulerFactory();
        IScheduler sc = sf.GetScheduler();
        sc.ScheduleJob(job, trigger);

        sc.Start();
    

我想在一个类中获取这个值。(smsjob)

   public class SmsJob : IJob 
     
      public virtual void Execute(IJobExecutionContext context)
      
          HttpContext.Current.Application["Setting"]; 
      
   

但我的问题是:HttpContext.Current 为空,为什么 HttpContext.Current 为空?

编辑: 当我在页面的另一类中使用此代码时,它可以工作,但在此类中我得到了错误。

【问题讨论】:

【参考方案1】:

只有当您在处理传入请求的线程中访问它时,HttpContext.Current 显然不是null。这就是“当我在另一类页面中使用此代码时”它起作用的原因。

它在调度相关类中不起作用,因为相关代码不是在有效线程上执行的,而是在后台线程上执行的,它没有关联的 HTTP 上下文。

总的来说,不要使用Application["Setting"] 来存储全局的东西,因为它们不像你发现的那样是全局的。

如果您需要将某些信息向下传递到业务逻辑层,请将其作为参数传递给相关方法。不要让业务逻辑层访问 HttpContextApplication["Settings"] 之类的东西,因为这违反了隔离和解耦的原则。

更新: 由于async/await的引入,此类问题出现的频率更高,可以考虑以下tip,

一般来说,您应该只在少数情况下调用HttpContext.Current(例如在 HTTP 模块中)。在所有其他情况下,您应该使用

Page.Contexthttps://docs.microsoft.com/en-us/dotnet/api/system.web.ui.page.context?view=netframework-4.7.2 Controller.HttpContexthttps://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.controller.httpcontext?view=aspnet-mvc-5.2

而不是HttpContext.Current

【讨论】:

另外,请记住,当使用关键字async/await 时,await 后面的行不一定是处理传入请求的同一线程。在您的第一个 await 之前参考 HttpContext.Current 以确保避免使用 NullReferenceException (我在它工作的地方有 sen 函数,在其他地方没有,所以保持一致是关键) @Lex Li 但是不会将 Session 存储在 Singleton 类中让所有用户共享同一个会话 Lex 有什么解决办法吗?我想访问类库中的当前用户。 @Lex Li 你有什么建议? @Lex Li 言归正传。您使用了不必要的丰富多彩的语言,这会掩盖您的答案。【参考方案2】:

尝试实现Application_AuthenticateRequest 而不是Application_Start

这个方法有一个HttpContext.Current 的实例,与Application_Start 不同(它在应用生命周期中很快触发,很快就没有HttpContext.Current 对象)。

希望有帮助。

【讨论】:

谢谢,但是当我在另一个类中使用此代码时,我得到了价值,但在这个类中 HttpContext.Current 为空。 正如我所说,这一切都是从Application_Start 调用的。将它移到 global.asax 中的 Application_AuthenticateRequest 下,它会起作用! '对象引用未设置为对象的实例。'对于HttpContext.Current 让我们continue this discussion in chat【参考方案3】:

在具有集成模式的 IIS7 中,CurrentApplication_Start 中不可用。有一个类似的线程here。

【讨论】:

以上是关于为啥 HttpContext.Current 为空?的主要内容,如果未能解决你的问题,请参考以下文章

HttpContext.Current 在异步回调中为空

HttpContext.Current.User.Identity.Name 为空

HttpContext.Current.User.Identity.Name 为空

HttpContext.Current 在 TokenCache.BeforeAccess 上为空

ServiceStack - System.Web.HttpContext.Current.Session 为空

异步 HttpContext.Current 为空null 另一种解决方法