Intercepting Filter Pattern Ile ASP.NET MVC Controller Action

Selamlar;

Intercepting Filter şablonu ile kullanıcıdan gelen istek (request) işleme alınmadan önce filitreler kullanılarak süzgeçten geçirilir.Örneğin bir filter ile user’ın işlem öncesi hangi ortamdan geldiği kontrol edilebilir. Filitre HttpRequest.Browser’dan user’ın mobile bir araçtan gelip gelmediğini  kontrol edip, duruma göre ilgili action’a yönlendirebilir. Böylece mobile’den gelen user için daha farklı ekranlar gösterilir.

inter

Intercepting Filter tasarım şablonunun merkezinde filtreler bulunur. Mvc’de ActionFilter olarak belirlenen classlar, peş peşe dizilerek herbiri için gelen request farklı işleme tabi tutulabilir.

browserFilter

Yukarıdaki diagramda görüldüğü gibi birden fazla filtre peş peşe eklenerek gelen request işleme tabi tutulmuştur. Sıradaki her filtre kendisine yüklenen görevini yerine getirdikten sonra kontrolü FilterManager yardımı ile kendinden sonraki filtreye bırakır. Eğer işlem esnasında filtrelerden birisi hatalı bir duruma düşerse mesela kullanıcı login olmamış ise işlem durdurulur. Bir sonraki filitreye geçilmez ve bu filter için tanımlanmış aksiyon gerçekleştirir. Mesela login sayfasına yönlendirilir.

Mvc’de Interceptor pattern’i incelemeden önce aşağıda görüldüğü gibi mvc’de kullanılan yapılara bir göz atalım.

Mvc’de birçok filter attribute vardır. Örnek vermek gerekirse AuthotizeAttribute, OutputCacheAttribute gibi. Biz de istersek ActionFilterAttribute sınıfından kendimize özel Custom Action Filiterlar yaratabiliriz. Bu konu ile ilgili makaleme buradan ulaşabilirsiniz. Aşağıda görüldüğü gibi  tüm bu attributelar System.Web.Mvc.GlobalFilterCollection ile global seviyede kaydedilir.

Action filterlar IActionFilter  interface’inden türetilir. İstresek filitreleri action başlamadan veya bittikten sonra devreye sokabiliriz. Buna pre-action ve post-action logic denmektedir. OnActionExecuting ve OnActionExecuted methodları ile tanımlanırlar.

ASP.NET MVC’de action filterlar ile çalışmak filter provider sayesinde çok rahat ve esnektir. 2 çeşit filter provider vardır. Bunlar FilterAttributeFilterProvider ve ControllerInstanceFilterProvider.  Aynı şekilde burda da custom filter provider yazabiliriz. Filitreleme yapılırken action’a yada controller’daki tüm actionlara bağlanabilirler. Aşağıda Custom ConditionalFilterProvider gözükmektedir.

Bu provider’ı aşağıdaki gibi register ederiz.

Var olan bir provider’ı aşağıdaki gibi kaldırırız.

Interception Mechanism Nedir?

Bildiğiniz gibi design ortamında gevşek bağlı yapılar hem ilerde genişletebilmek için hemde başka bir yapının siteme eklenmesinde büyük yarar sağlar. Aslında filterlar, bahsettiğimiz bu rahatlığı bize sağlarlar. Fakat daha büyük bir değişikliğe gidilmek istendiğinde yeni custom filterlar oluşturmak zorunda kalabiliriz.

Yeni bir custom filter oluşturulurken ve var olan yapıya eklenirken aşağıdaki konulara dikkat edilmelidir.

  • Eğer bir controller içindeki action bir başka controllerdaki action’a call yapıyor ise buna filter konmamalıdır. Filter tek bir controller veya action için tasarlanmalıdır.
  • Yaratılan custom filter provider’lar belli bir mantık ile tanımlanan bir class veya yapıdan sisteme dahil edilmelidirler. Mesela dependency injection buna güzel bir örnektir.
  • Herzaman action işeltilmeden veya işletildikten sonra yani OnActionExecuted veya OnActionExecuting  durumlarında ilgili filterlar işletilmelidir.

Interception  3 temel  işleyişe göre çalışmaktadır. Belirlenen koşulları sağlama, Call handlers, and Interceptors.

Örnek olarak bir MVC application’da tüm controller’ları intercept eden bir uygulama yazalım:

Yukarıda görüldüğü gibi controller’ın ilgili action’ında işleme başlamadan önce ve bitiminde; daha sonra sonuç değerlerini almadan önce ve sonrasındaki adımlar controller’ın action’ın ve methodun isimleri yazdırılarak loglanmıştır.

[LogAttribute] attribute şeklinde controllerın veya action’ın başına konarak kullanılır. Controller’ın başına [LogAttribute] filter’ı konur ise controller altındaki tüm actionlara filter atanmış olur.

Ayrıca bu filter’ı global filterlara aşağıdaki  gibi eklemek gerekmeketedir.

intercept

Şimdi de mvc’de login olunup olunmadığına bakılıp, duruma göre login ekranına yönlendirilen bir action filter yazalım.  Önce aşağıda görüldüğü gibi action’a başlamadan önce pre-action durumunda ilgili koşula bakarak yani Session[“Login”]’in null olup olmadığna bakılır. Koşul sağlanıyorsa filterContext.Result değeri “Login” action olarak akış intercept edilip gidilmek istenen yer engellenir.

HomeController.cs

Login.cshtml: Login için Username ve Password girildikten sonra Gönder button’una basılınca Login [Post] action’ına gidilir. Ve yukarıda görüldüğü gibi  Session[“Login”] = name; değeri atanır ki ilgili koşul sağlansın ve filter’a takılıp tekrardan login ekranına düşülmesin.

Index.cshtml: Aşağıda görüldüğü gibi filter koşulu sağlanmadığı için akış bölünmemiş ve Index.cshtml’e gelinmiştir. Çıkış button’una basılınca HomeControl.cs’deki Logout action’ına gidilip Session[“Login”] = null; değeri atanarak tekrardan girilmeye çalışılınca filiter’a takılıp login ekranına düşülmektedir.

RouteConfig.cs:

İlgili video aşağıdadır.

Istenir ise filterlar  aşağıda görüldüğü gibi art arda eklenerek kullanılarbilirler.

Sonuç olarak günlük hayatımızda özellikle mvc’de farkına varmadan kullandığımız birçok design pattern vardır. İşte Intercepting Filter Pattern’da farkına varmadan kullandığımız design pattern’lardan biridir.

Geldik bir makalenin daha sonuna.

Yeni bir makalede görüşmek üzere hoşçakalın.

Herkes Görsün:

Sevebilirsin...

3 Yanıt

  1. Ceyda diyor ki:

    Selamlar hocam.

    Elinize sağlık harika bir yazı olmuş.
    Üniversitelere seminere geliyormusunuz? Eğer geliyorsanız ITU’ye de gelirmisiniz hocam. Öğrenecek daha çok şeyimiz var. Mesela bu konu şu an karşılaştığımız sorunları okadar pratik bir hale getiriyor ki. Kimbilir daha basit ne yollar var hocam…

    Daha nice kodlara hocam..

  2. Ömer diyor ki:

    Çok güzel bir yazı olmuş hocam. İlk iş bizim projedeki tüm login ve authentication yapısını buna çeviricem.
    Çok teşekkürler.

  3. Murat diyor ki:

    Selamlar hocam;

    User’ın mobile’den mi yoksa web’den mi geldiğini bu filter yöntemi ile belirlemeye karar verdim.
    Gerçekten çok işime yaradı. Elinize sağlık hocam.

    Çok teşekkürler..

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir