ASP.Net MVC Denetleyici Oluşturucularında oturum boş


89

Denetleyicilerin oluşturucularında Oturum neden boş? Eylem yöntemlerinden erişilebilir. Muhtemelen, MVC Yönlendirme çerçevesi bir Denetleyiciyi yenilemekten sorumlu olduğu için, o noktada Oturumu (yeniden) başlatmadı.

Bunun tasarım gereği olup olmadığını bilen var mı ve öyleyse neden?

[Bir Geç Yükleme Modeli kullanarak sorunu aşmayı başardım.]

Yanıtlar:


80

Andrei haklı - bu boş çünkü ASP.NET MVC çerçevesi altında çalışırken, denetleyici sınıfı beklediğiniz gibi oluşturulduğunda HttpContext (ve dolayısıyla HttpContext.Session) ayarlanmıyor, ancak daha sonra ayarlanmış ("enjekte") ControllerBuilder sınıfı tarafından. Yaşam döngüsünün daha iyi anlaşılmasını istiyorsanız, ASP.NET MVC çerçevesini (kaynak kullanılabilir) aşağı çekebilir veya şu sayfaya başvurabilirsiniz: bu sayfa

Oturuma erişmeniz gerekiyorsa, bir yol, "OnActionExecuting" yöntemini geçersiz kılmak ve o zamana kadar kullanılabilir olacağı için, oradan erişmek olacaktır.

Bununla birlikte, Andrei'nin önerdiği gibi, eğer kodunuz Oturuma bağlıysa, potansiyel olarak birim testleri yazmak zor olabilir, bu nedenle, Oturumu daha sonra farklı bir sınıfla değiştirilebilecek bir yardımcı sınıfa yerleştirmeyi düşünebilirsiniz. Ünite testleri altında çalışırken web sürümü, bu nedenle kontrol cihazınızı web'den ayırın.


3
Bunun HttpContext hakkında doğru ifade olduğundan emin değilim. Aslında tüm akışın başlangıcında inşa edildi. Burada ayrıntılı akış hakkında biraz bilgi edinebilirsiniz beletsky.net/2011/06/inside-aspnet-mvc-route-to-mvchanlder.html veya reflektörü kullanabilir ve httpContext başlatıldığında kendinizi bulabilirsiniz - bu satır 1556'da .cs.
Alexey Shcherbak

@AlexeyShcherbak Zaten oluşturulmuş olabilir - OP, MVC denetleyicisinin Session özelliğinde ayarlanıp ayarlanmadığıyla ilgilidir. yani halka açık HttpSessionStateBase Session {get; } on System.Web.Mvc.Controller Bunlar farklı şeylerdir.
MemeDeveloper

62

Buradaki diğer yanıtlara ek olarak, Controller.Sessionkurucuda doldurulmamış olsa da, oturuma şu şekilde erişebilirsiniz:

System.Web.HttpContext.Current.Session

Bunun kontrol cihazınızın test edilebilirliğini potansiyel olarak azalttığı konusunda standart uyarı ile.


3
Bu iki oturum özelliğinin her birinin türü farklıdır ve oturum durumunun kendisine bir referans tutmayı planlıyorsanız önemli olabilir.
BrianCooksey

@BrianCooksey ne farklı?
MichaelMao

1
Controller.Session, System.Web.HttpSessionStateBase türündedir (bkz. Msdn.microsoft.com/en-us/library/… ) ancak System.Web.HttpContext.Current.Session türü System.Web.SessionState.HttpSessionState (bkz. Msdn .microsoft.com / en-us / library /… )
BrianCooksey

Eski cevap, ancak bunun VS2019 MVC kurucusunda System.Web.HttpContext.Current.Sessionda olduğunu söylemek istedim null.
jp2code

HttpSessionStateWrapper yapıcısını kullanarak sarmalayarak bir HttpSessionState'den bir HttpSessionStateBase alabilirsiniz.
Fabricio

11

Seans, yaşam döngüsünün sonraki aşamalarında enjekte edilir. Neden yine de kurucuda oturuma ihtiyacınız var? TDD için ihtiyacınız varsa, oturumu alay edilebilir bir nesneye sarmalısınız.


1
Andrei Rinea'ya eklemek gerekirse, bu onun bahsettiği tekniğin belirli bir örneğidir: iridescence.no/post/…
murki

4
Kurucularım sırasında Oturuma erişmek istiyorum, böylece daha önce depolanan oturum bilgilerine erişebilirim. Evet, OnActionExecuting yöntemini geçersiz kılabilirim, ancak bu kesinlikle zarif bir çözüm değil.
Chris Arnold

8

Oturumunuzu ayarlamak için Initialize yöntemini geçersiz kılabilirsiniz.

protected override void Initialize(RequestContext requestContext)

2

Bir IoC Container kullanıyorsanız HttpSessionStateBase, Sessionnesne yerine enjekte etmeyi ve kullanmayı deneyin :

private static Container defaultContainer()
{
    return new Container(ioc =>
    {
        // session manager setup
        ioc.For<HttpSessionStateBase>()
           .Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session)); 
    });
}

2

Bu cevap bazı insanlar için faydalı olabilir

Initialize yöntemini geçersiz kılarsak, temel sınıfı istek bağlamı ile başlatmamız gerekir: base.Initialize (requestContext);

protected override void Initialize(RequestContext requestContext)
        {
            base.Initialize(requestContext);
           

        }

Kullanışlı. Yöntem imzasının olduğuna dikkat edin protected override void Initialize(System.Web.Routing.RequestContext requestContext).
Martin_W
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.