İçeriğe geç

ASP.NET Core MVC Filter Yapısı

Filter Nedir
Filter yapısı bizlere bir requestin response haline dönüşen sürecindeki belirli aşamalardan önce veya sonra kod çalıştırmanıza imkan tanır. ASP.NET Core MVC içinde hali hazırda birçok filter mevcuttur ve bunun yanında custom filter hazırlamak mümkündür. Bu yapı sayesinde uygulama içinde kod tekrarı yapmaktan kaçınabiliriz.

 

Filter Tipleri
Her filter tipi farklı aşamalarda devreye girer ve farklı görevleri yerine getirmek için tasarlanır. Filter tiplerini aşağıdaki gibi sıralamak mümkündür.

 

– Authorization filters
İlk çalışan filter tipidir. Bu filter yapısı ile geçerli request için kullanıcının yetkili olup olmadığını kontrol ederiz. Kullanıcı geçerli request için yetkisiz durumda ise geri kalan işlemler devam edemez. Bunun yanında kendimiz de custom authorization filter hazırlayabiliriz. Aşağıda 18 yaş kontrolünü gerçekleştiren bir Authorization Filter örneğini inceleyelim.

    public class Over18Requirement : AuthorizationHandler<Over18Requirement>, IAuthorizationRequirement
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, Over18Requirement requirement)
        {
            if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth))
            {
                return Task.FromResult(0);
            }

            DateTime dateOfBirth = Convert.ToDateTime(context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth).Value);
            int age = DateTime.Today.Year - dateOfBirth.Year;

            if (age >= 18)
            {
                context.Succeed(requirement);
            }

            return Task.FromResult(0);
        }
    }

Görüldüğü üzere AuthorizationHandler sınıfını base alan bir sınıf hazırladık. AuthorizationHandler sınıfı abstract bir sınıftır ve generic tip olarak IAuthorizationRequirement türünden bir nesne istemektedir. Bu sebeple Over18Requirement isimli sınıfımızı bu interfaceden türettik. Sonrasında HandleRequirementAsync isimli metodu override ettik ve gelen context değerinden user bilgisine ait DateOfBirth değerinin 18den büyük olup olmadığını sorguladık.

Bu hazırladığımız filter için Startup sınıfı içinde konfigurasyon yapmamız gerekmektedir. Bunu Configuration metodu içerisinde aşağıdaki gibi belirtmeliyiz.

            services.AddAuthorization(options =>
            {
                options.AddPolicy("Over18", policy => policy.AddRequirements(new Over18Requirement()));
            });

Hazırladığımız filter yapısını aşağıdaki şekilde attribute olarak kullanarak test edebiliriz. (.Net Core 2.0 üzerinde test edemiyoruz. Çünkü preview 2.0 sürümünde olduğundan attribute desteği henüz dahil edilmemiş.)

        [Authorize(Policy = "Over18")]
        public IActionResult Index()
        {
            // iş mantığı
            return View();
        }

– Resource filters
Bu filter tipi yalnızca Authorication filter tipinden sonra çalışır. Çoğunlukla short-circuit durumlar için kullanılır. Örneğin response bir önbellekte bulunuyorsa pipeline geri kalan işlemlerden kaçınır. Bu filter tipini kullanmak için IResourceFilter interface türetmesi yapmalıyız. Bu interface içinde bulunan OnResourceExecuting ve OnResourceExecuted metotlarını implement ederek Resource Filter hazırlığını tamamlayabiliriz. Örnek olması açısından bu adresi kullanabilirsiniz.

– Action filters
Action filter yapısı bir controller içindeki metot çalışmadan hemen önce veya sonra işler. Action yürütülmeden hemen öncesinde veya sonrasında araya bir iş mantığı yerleştirmek amacıyla kullanılır. Bir Action Filter hazırlamak için IActionFilter interface tipinden türetme yapmalıyız.

public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // action çalışmadan önceki yürütülecek iş mantığı
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // action çalışmasından sonraki yürütülecek iş mantığı
    }
}

Action Filter kullanımı için ilgili metoda attribute tanımı yapılmalıdır.

        [TypeFilter(typeof(SampleActionFilter))]
        public IActionResult Index()
        {
            return View();
        }

Senaryo: Şöyle bir senaryo düşünebiliriz. İlgili action içinde bir hata ile karşılaşılması durumunda doğal olarak exception üretilir. Bu aşamada OnActionExecuted metodu çalışır mı? Çalışırsa excepion üretimi öncesi mi çalışır yoksa sonrası mı çalışır? Ev ödevi… 🙂

– Exception filters
Bu filter yapısı response tarafında oluşmuş olan hataları yönetmek için kullanılır. ExceptionFilterAttribute abstract sınıfı base alınarak hazırlanmalıdır. Bu abstract sınıf içinde OnException ve OnExceptionAsync olmak üzere 2 farklı metot bulunmakta ve bunları override ederek kendi exception filter hazırlığımızı tamamlayabiliriz.

– Result filters
Result filter tipi bir action başarılı sonuçlandığında response üretmeden hemen önce veya sonra çalışır. Bu filter için ActionFilterAttribute abstract sınıfı içinde bulunan OnResultExecuted, OnResultExecuting ve OnResultExecutionAsync metotlarını kullanmalıyız.

 

Filter Kapsamı ve Yürütme Sırası
Bir filter eklemenin 3 yolu vardır: Action metot aracılığıyla, Controller sınıf aracılığıyla ve global olarak. Birden fazla filter tipiniz varsa bunların çalışma sırası aşağıdaki şemadaki gibi olmaktadır. Öncelikle Global filter devreye girer sonrasında Controller sınıf filter ve son olarak metot filter olarak devam eder.

 

Short Circuiting(Kısa Devre)
Short Circuiting kısa devre anlamına gelmekte ve hazırlayacağınız filter yapısı içinde bu özelliği kullanarak o an için response döndürmeniz mümkün olabilir ve geri kalan işlemleri pasifize etmiş olursunuz. Context nesnesi içinde yer alan Result pazarmetresine değer ataması ile bu özelliği test edebilirsiniz.

    public class ExampleFilterAttribute : Attribute, IActionFilter  
    {  
        public void OnActionExecuting(ActionExecutingContext context)  
        {    
            context.Result = new ContentResult()  
            {  
                Content = "Short circuit filter"  
            };  
        }  

        public void OnActionExecuted(ActionExecutedContext context)  
        {  
 
        }  
    }  

 

Yararlanılan Kaynaklar:
https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters
http://www.c-sharpcorner.com/article/working-with-filters-in-asp-net-core-mvc

Tarih:ASP .NET Core

İlk Yorumu Siz Yapın

Bir cevap yazın

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.