web-dev-qa-db-fra.com

Pourquoi HttpContext.Current est null?

J'ai une valeur que j'utilise dans toute l'application; J'ai mis ceci dans 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();

  }

et dans SmsSchedule

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

Je veux obtenir cette valeur dans une classe. (Smsjob)

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

mais mon problème est: HttpContext.Current est null, pourquoi HttpContext.Current est null?

Edit: Quand j'utilise ce code dans une autre classe d'une page cela fonctionne, mais dans cette classe j'obtiens l'erreur.

40
ar.gorgin

Clairement HttpContext.Current n'est pas null que si vous y accédez dans un thread qui gère les demandes entrantes. C'est pourquoi cela fonctionne "lorsque j'utilise ce code dans une autre classe d'une page".

Cela ne fonctionnera pas dans la classe liée à la planification car le code pertinent n'est pas exécuté sur un thread valide, mais sur un thread d'arrière-plan, auquel aucun contexte HTTP n'est associé.

Dans l'ensemble, n'utilisez pas Application["Setting"] pour stocker des éléments globaux, car ils ne sont pas globaux, comme vous l'avez découvert.

Si vous devez transmettre certaines informations à la couche de logique métier, transmettez-les en tant qu'arguments aux méthodes associées. Ne laissez pas votre couche logique d’entreprise accéder à des éléments tels que HttpContext ou Application["Settings"], car cela viole les principes d’isolement et de découplage.

Mise à jour: en raison de l'introduction de async/await c’est plus souvent que de tels problèmes se produisent, vous pouvez donc envisager le conseil suivant,

En général, vous ne devriez appeler que HttpContext.Current dans seulement quelques scénarios (dans un module HTTP par exemple). Dans tous les autres cas, vous devriez utiliser

au lieu de HttpContext.Current.

83
Lex Li

Dans IIS7 avec le mode intégré, Current n'est pas disponible dans Application_Start. Il y a un fil similaire ici .

7
Tasos K.

essayer d'implémenter Application_AuthenticateRequest au lieu de Application_Start.

cette méthode a une instance pour HttpContext.Current, contrairement à Application_Start _ (qui se déclenche très tôt dans le cycle de vie de l'application, suffisamment tôt pour ne pas tenir un HttpContext.Current objet encore).

j'espère que ça t'as aidé.

7
geevee