Mvc Rooting & Custom Constraint & Custom Action Filters

Bugünkü makalemizde amaç bir Mvc projesine request geldiği zaman izlenilecek işlem adımları ve gelen bu request’deki parametrelere göre daha en baştan yapılabilecek filitreleme ve kısıtlamalardır.Daha controller veya action’a gelmeden yapılan bu filitrelemeler, uygulamamıza performance ve güvenlik anlamında büyük katkı sağlamaktadır.Şimdi isterseniz routing kavramı ile konuya giriş yapalım.

Routing:

Routing, kullanıcının veya arama motorlarının sitenin URL’inde anlamlı ifadeler görebilmesini ve bu anlamlı ifadelerin, uygulama tarafında hangi controller ve action’a karşılık gelidiğini gösteren bir road mapdir.

Anlamlı ifadede ki amaç, google indexlemelerinde yada sosyal ağlardaki paylaşımda  sadelik ve anlaşılabilirliği korumaktır.

Visual Studio’daki yeri, App_Start/RouteConfig.cs olan dosyanın içeriği aşşağıdaki gibidir:

routingpattern

route

Yukarda klasik bir MVC request’i görmekteyiz. Control, MvcHandler’a eriştiği zaman, MvcHandler RouteData’dan controller’ın parametrelerini ayıklar.Ve gerekli parametreleri controller’a gönderir. Tüm controllelar IController interface’inden türetilmiştir.

rout

Yukarıda görüldüğü gibi Url’den request gelince RouteHandler devreye girer.Routing her zaman RouteConfig’de, istemciden gelen url’e uyan route’u en üstten aşşağıya doğru tarayarak bakar.En sona en genel route yani default route konur.Aranan koşullara uygunluk, url segmesinden bakıldıktan sonra, eğer geçerli koşullar sağlanmış ise ilgli controller’ın ilgili action’a gidilir.Test amaçlı  yukarıdaki RoutConfig örneğinde Url kısmına http://localhost:4443/Home/ActionSelector yazarsak Filter Route’una gidecektir. http://localhost:4443/Home/ yazarsak Default route’una gidecektir.

rootCheck

ImageSource: https://www.red-gate.com/simple-talk/wp-content/uploads/imported/1407-img92.jpg

 

Şimdi RoutConfig dosyamızın başına yani en tepeye alltki yeni rout’u ekleyelim:

Yukarıda route.config’e yeni bir constraint ekledik.Bu constraintde regex ile gelen id parametresi 1 ile 6 arasında olması gerektiği belirtilmiştir. Eğer Url’e: http://localhost:4443/Home/ActionSelector/6 yazar isek id değeri olan 6, kural’a uyduğu için ActionSelectorFiltered sayfasına gider. Eğer http://localhost:4443/Home/ActionSelector/8  yazar isek id değeri 8, 1 ile 6 arasında olamığı ve kurala uymadığı için bir altındaki route olan ActionSelector’e gider.

Projeye Install-Package RouteDebugger yüklenirse yazılan url’e göre Route Data’nın hangi rule’uyduğu adım adım görülebilir.

page

Yukarıda görüldüğü gibi http://localhost:4443/Home/ActionSelector/8  şeklinde bir request id=[1-6]’ya uymamaktadır.Bu nedenle bir aşşağısındaki route olan ActionSelector’e yönlenmiştir.

Custom Route Constraint:

Diyelimki işi daha ileriye götürdük.Siteye girilen browser’a göre filter yapıcaz.Bunu yukarda da bahsettiğim gibi daha en başta yapıcaz.Yani Controller ve action’a gelmeden bir filitrelemede bulunacaz.Bu bize hem zaman hem de performans kazandıracak.Bunun için öncelikle IRouteConstraintden türemiş bir sınıfa ihtiyacımız var.

Daha sonra Firefox’da siteye giriş yapalım.Hangi UserAgent’da bulunduğumuzu http://www.whatsmyuseragent.com/ dan bakabiliriz.İçinde Firefox kelimesi arıyacaz.

Şimdi RoutConfig dosyamızın başına yani en tepeye alltki yeni rout’u ekleyelim:

Artık yandaki url’i http://localhost:4443/Home/ActionSelector/6 FireFox’dan açarsak. ActionSelectorFilteredFirefox route’una gittiğini Chrome’dan açarsak ActionSelectorFiltered’a gittiğini görücez.

Istersek bir de Action üstüne yada controller üstüne tanımli attribute yani filter kullanabiliriz.

Örnek amaçlı bir sayfa yapalım.Sadece Explorer’da açılsın.Örnek kodumuz aşşağıdaki gibidir.

RoutConfig.cs aşşağıdaki kodu ekleyelim:

Şimdi HomeController’ımızdaki IndexExplorer Action’ına gidelim ve aşşağıdaki kodu ekleyelim:

İşte Sadece [Explorer ] ekliyerek bu sayfanın sadece explorerda açılması sağlayabildik.Çeşitli filter interfacelerini aşşağıda görebilirsiniz.

filter

Bir de isterseniz ActionFilterAttribute’una bakalım.OnActionExecuting yani action sırasında ve OnActionExecuted yani action çalıştırıldıktan sonra diye iki method’u vardır.

Alttaki uygulamanın amacı action başlamadan önce ve bittiği zaman bir bildirim vermesidir.

HomeController’daki kod aşşağıdadır:

 

Yukarıdaki örnekte görüldüğü gibi WriteSteps attribute eklenmiş Index sayfasında başlangıç ve bitişinde aşşağıda görülen mesajları alırız.

screen

 

 

Yukarıda görüldüğü gibi IndexExplorer’da WriteSteps attribute’u iki kere çağrılmıştır.Ve Order ile çalışma sırası belirlenmiştir.

Sonuç olarak IndexExplorer çağrılınca çıkan mesaj aşşağıdaki gibidir.

screen2

Sonuç:

Mvc’nin güçlü routing yapısına derinlemesine inceledik.

Görüldüğü üzere routing’de daha controller’a gelmeden yada action zamanında istendiği gibi çeşitli müdahalelerde yani filter constraintlerinde  bulunula bilmektedir.

Routing sırasında regular expression ile kendi constraintlerimizi de yazabiliriz.

Bir sonraki makalede görüşmek üzere herkese hoşçakalın.

Source Code:http://www.borakasmer.com/projects/MvcFilter.rar

Source:

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

5 Cevaplar

  1. fatih dedi ki:

    Merhabalar, ActionMethodSelectorAttribute’de bir bug mu var? aşağıdaki kodda [AcceptOnlyMain] sadece post actionda ekli olmasında rağmen diğer Get methodda da tetikleniyor.

    [HttpGet]
    [Route(“”)]
    public IActionResult Index()
    {
    return View();
    }

    [HttpPost]
    [Route(“”)]
    [AcceptOnlyMain]
    public IActionResult Index(int a)
    {
    return View();
    }

    • borsoft dedi ki:

      Selamlar,

      Acaba [AcceptOnlyMain]’ı bir de Controller’ın da üstüne koymuş olmıyasınız ?

      • fatih dedi ki:

        Olmadığına eminim :) her iki url’de aynı olduğundan mı kaynaklanıyor acaba. buradaki yaklaşımı pek anlamış değilim.

      • fatih dedi ki:

        Biraz araştırmamın sonucunda çözümü buldum. Problemin sebebi [AcceptOnlyMain] Attribute’nin
        [HttpPost] Attribute’den önce çalışıyor olması. Burada order mekanizması devreye girdiği için [AcceptOnlyMain(Order = 1)] şeklinde yazdığımda sorun çözülüyor. fakat çok fazla attribute sahibim ve yanlış bir şey yapmamak adına alternatif yol arayacağım. Kolay gelsin..

  1. 10 Temmuz 2016

    […] Bora Kaşmer – MVC Rooting […]

borsoft için bir cevap yazın Cevabı iptal et

E-posta hesabınız yayımlanmayacak.