ASP.NET MVC 1 HttpContextBase bir HttpContext nesnesi nasıl alabilirim?


155

Bazı WebForms / MVC agnostik araçları ile çalışıyorum ve HttpContextbir HttpContextBasenesneye başvuru verilen bir örnek almak gerekiyor . Bunu kullanamıyorum HttpContext.Currentçünkü asenkron olarak da çalışması gerekiyor ( asenkronize bir istek sırasında HttpContext.Currentdöner null). Biliyorum HttpContextWrapper, ama yanlış gidiyor.

Yanıtlar:


250

En basit yol, uygulamayı almak ApplicationInstanceve Contextözelliğini kullanmaktır :

// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;

( yorumlarda bunu kaydeden İshmael Smyrnow'a teşekkürler )

Orijinal cevap:

Özellikle HttpContextBaseteslim ettiğiniz örnek HttpContextWrapperçalışma zamanında türdeyse yapabilirsiniz. Aşağıdaki örnekte bunu nasıl yapabileceğiniz gösterilmektedir. FooBağlamı kabul eden, HttpContextBaseancak üçüncü taraf bir derlemede (değiştirmek için iyi şansa sahip olamayacağınız) bir yöntemin çağrılmasını bekleyen bir yöntem çağırmanız gerektiğini varsayar HttpContext.

void Foo(HttpContextBase context) 
{
    var app = (HttpApplication) context.GetService(typeof(HttpApplication));
    ThirdParty.Bar.Baz(app.Context);
}

// Somewhere in assembly and namespace ThirdParty,
// in a class called Bar, there is Baz expecting HttpContext:

static void Baz(HttpContext context) { /* ... */ }

HttpContextBaseGetServicedestekleme olarak adlandırılan bir yöntemi vardır IServiceProvider. GetServiceBir geçersiz kılma HttpContextWrapperdelege GetServicesarılmış uygulanması HttpContextörneği. GetServiceUygulanması HttpContextgibi olağan şüpheliler için sorguya izin verir HttpApplication, HttpRequest, HttpResponsevb. Sadece ContextHttpApplication adında bir özelliğe sahip olan ve bir örneği döndüren bu olur . Yani bir sarılmış de alır sorarak Örneğin için aracılığıyla okuyarak takip döndürülen özelliği örneği.HttpContextHttpContextHttpContextBaseHttpApplicationGetServiceContextHttpApplication

Aksine HttpContextBase, GetServicebir kamu üyesi olarak görünmüyor HttpContextama olmalarındandır HttpContextuygular IServiceProvider.GetServiceexplicity süre HttpContextBasedeğil.

FooArtık test edilemediğini unutmayın, çünkü HttpContexttest sırasında altta yatan şeyi açabilmeye dayanır ve ilk etapta sahte / saplama yapmak imkansızdır. Ancak bu cevabın amacı, “HttpContextBase'den bir HttpContext nesnesini nasıl alabilirim?” Sorusunu tam anlamıyla ele almaktır . Gösterilen teknik, kendinizi değiştirmek için lükse sahip olmadığınız bileşenler arasında kendinizi sandviç bulduğunuz durumlarda kullanışlıdır.


3
Çok ilginç bir cevap, sadece kendimi MVC'de HttpContext'i bir Hata Filtresinden ELMAH'a günlüğe geçirmek için kullandım.
Chris Marisic

1
güzel cevap, biraz kazma gerektiren bahis? :)
longhairedsi

mükemmel cevap! Özellikle Elmah'ımda MVC denetleyicisine github.com/alexanderbeletsky/elmah.mvc.controller/blob/master/…
Alexander Beletsky

36
Bir HttpContextBase ile arayamadınız context.ApplicationInstance.Contextmı?
İshmael Smyrnow

@IshmaelSmyrnow Lanet olsun, Http*Basegeri dönen tüm varyasyonlar arasında bunu nasıl kaçırdığım HttpContextBase. : P Cevabı güncelleyeceğim.
Atif Aziz

32

Yapabilirsin,

var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);

16
-1 bu yanlış yoldur, Bağlamınız varken Tabanı verir, tersi değil.
Chris Marisic

14

Yapamazsın.

Bütün amacı HttpContextBase, somut HttpContextsınıfa olan bağımlılığı soyutlamaktır . O iken olabilecek somut içerirler HttpContext (olduğu gibi httpContextWrapper) , diğer uygulamalar ile hiçbir ilgisi olabilir HttpContext.

En iyi seçeneğiniz, HttpContextBasesizin için bir alabileceğiniz özel bir Soyut Fabrika tanımlamaktır , çünkü her zaman HttpContexta HttpContextWrapper.


13
Bu arada, korkunç bir şekilde yapıldı - birim testleri için bir kurulum olmasını istediğimi anlıyorum ve soyutlama katmanlarını anlıyorum - ama bir HttpContext bekleyen mevcut ASP.NET sınıflarını kullanmak istediğinizde WTH yapmanız gerekiyor mu? ( msdn.microsoft.com/en-us/library/… gibi )
marq

IHttpHandlerSadece birim testleriniz için (Yanıt sarmalayıcıları) içine bir parça soyutlama koymak zorunda kaldığınız uygulamaları test etmeyi deneyin, ki bu doğru hissetmez, ancak tek seçenek olur.
Chris S
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.