Asp.Net MVC - IExceptionFilter Implementasyonu İle Hata Yakalama

By Burak TUNGUT - 9.3.2013 - 1 Yorum - Kategori Asp.Net MVC

Herkese merhabalar. Yaklaşık 2 haftadır yazmayı hatta yazacağımda uygulamak istediğim senaryoyu bile kafamda tasarladığım makalem ile karşı karşıyayız cool Geçtiğimiz 3 ay boyunca MVC patterni üzerine yoğunlaşmama rağmen bu alanda makale paylaşımlarımın eksik olduğumu gözlemledim. Aslında amacım Asp.Net MVC için düzenli ilerleyecek bir yazı dizisi hazırlamaktı fakat bu alandaki ilk makalemin başlığı, “Asp.Net MVC - Arama Motoru Dostu linkler için Custom Link Senaryosu” şeklinde olunca giriş seviyesi konuları biraz atlamış oldum cheeky

C# ile Web Forms ya da MVC olsun herhangi biri ile web projesi geliştiren herkes eminim ki aşağıdaki manzara ile karşılaşmıştır;

Asp.Net MVC Exception

“Kahretsin!! Evettt” diyenleri duyar gibiyim J Sarı arka plan üzerine kurulmuş şu sayfayı gördüğümüzde hiç şüphesiz işlerin ters gittiği kesindir. Birde son müşteri için hizmete açılmış bir projede böyle bir şeyin olduğunu hayal edelim. Ya da vazgeçtim. Hayal etmesek daha iyi gibi. Pekte güzel bir hayal olmadı blush Tabi ki bu hayali daha doğrusu kabusun yaşanmaması için bir şeylerin yapılması gerekir.

Senaryomuzu Tanıyalım

Aslında yapılması gereken olgu için ipucunu daha önce verdim (Bknz.: Makale Başlığı). Asp.Net MVC platformunun bizler için sunduğu çeşitli hata ayıklama mekanizmaları mevcut.  Aklıma gelenler için bunları şöyle sıralıyabiliriz;

1.       Application_Error metodunun yazılması

2.       IExceptionFilter interface’ini implemente eden bir filter yazılması

3.       IIS Custom Error kullanılması

Aklıma gelen bu üç yöntemden OOP tekniklerine daha yatkın olduğu için ikincisini tercih ettim.

Bugünkü senaryomuz olabildiğince basit. Elimizde bir web projesi var. Ana sayfasında ise sadece “Hata Fırlat” ismine sahip ve tıklandığında ise Exception fırlatacak bir link olsun. Tabi ki bu linke tıklandığında daha önce herhangi bir hata yakalama işlemi yapılmadığı için, yukarıda lanetler okuduğumuz sarı arka planları bir sayfa ile karşılaşıyor oluruz.

Projeyi uygulamaya geçirme işlemine, controller ve action’lardan başlayalım. Bunun için içi boş bir MVC projesi oluşturalım ve HomeController altına Index, Throw ve Error adlı üç adet ActionResult ekleyelim.  Index adlı ve Error adlı actionlar için birer view oluşturalım. Throw adlı action için herhangi bir view oluşturmayalım. Hata fırlatacak action’ın view ile ne işi olur laugh

HomeController Sınıfının Kodları

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Throw()
        {
            throw new Exception("Ben Fırlatırım, Sen Yakalarsın!");
        }

        public ActionResult Error()
        {
            return View();
        }
    }

Yukarıda bahsettiğimiz gibi Throw action'ının bir view'e bağlanması gereksizdir. Dikkat ederseniz herhangi bir return işlemide bu metot içerisinde uygulanmamıştır. Hatta Visual Studio varsa return sözcüğünün bizim için gereksiz olduğunuda söyleyecektir.

Index Adlı View'in Kodları

@{
    ViewBag.Title = "Ana Sayfa";
}

<h2>Ana Sayfa</h2>
<a href="@Url.Action("Throw")">Hata Fırlat!</a>

Projemizi bu haliyle debug edelim ve hata fırlatılması için yukarıda oluşturduğumuz linke tıklayalım. Manzarayı tekrar tartışmaya gerek yok sanırım. Herhangi bir hata oluştuğunda kullanıcıya daha dost canlısı bir uyarı verdirmek içinde daha önce oluşturduğumuz Error result'ı için bir adet view ekleyelim.

Error Adlı View'in Kodları

@{
    ViewBag.Title = "Bir Hata Oluştu!";
}

<h2>Üzgünüm :( Bir Hata Oluştu!</h2>

Bir hata oluştuğunda son kullanıcıya yukarıdaki gibi bir sayfa yerine hatanın özkaynağınında bulunduğu bir sayfa gösterilmesi aynı zamanda bir güvenlik açığı oluşturacaktır.

Şimdi hata yakalam işlemine başlayalım. Bunun için öncelikle proje içerisinde ExceptionHandlerFilter adında bir sınıf oluşturup, IExceptionFilter interface'inden implemente edilmesini sağlayalım. İmplemente ettiğimiz bu arayüz içerisinde ezilmesini gerektiren ve adı OnException olan bir metot içerir. Biraz sonra üzerinde çalışacağımız bu metot parametre olarak ExceptionContext tipinde bir nesne taşır ve oluşan hata dahil, yönlendirme yapacağımız result alanlarının her birini içerisinde taşır.

ExceptionHandlerFilter Sınıfının Kodları

public class ExceptionHandlerFilter : IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            //Hata Loglandı
            //...
            filterContext.ExceptionHandled = true;
            var routeData = new RouteValueDictionary();
            routeData.Add("controller", "Home");
            routeData.Add("action", "Error");
            filterContext.Result = new RedirectToRouteResult(routeData);
        }
    }

Projemizde herhangi bir hata ile karşılaşıldığında tetiklenecek olan metot yukarıdaki gibidir. Bu metot içerisinde yapılacak en nadide işlemlerden biri hiç şüphesiz loglamadır. Makalemizdeki odak noktası bu filter'ın kullanımı olduğu için loglama işlemine değinmeden kaçı veriyoruz cheeky

Yaptığımızı varsaydığımız loglama işleminden sonra ise artık kullanıcıya bir hatanın oluştuğu bilidirilmelidir. Bunun için kullanıcının bulunduğu sayfa, yukarıda oluşturduğumuz Error view'ine bağlanmalıdır. Metot bu işlemi gerçekleştirebilmemiz için o anda execute edilmiş olan Result bilgisini filterContext adlı referans ile bize sunmaktadır. 

Gelen result bilgisi ne olursa olsun bir hata oluştuğu için yönlendirme yapılacaktır. Bu işlem için de RedirectToRouteResult adlı sınıf kullanılabilir. Bu yöntem ile yönlendirme yapılması için Route verilerininde girilmesi gereklidir. MVC'de bir route, execute işlemlerinin gerçekleştirilmesi için Controller ve Action bilgilerini mutlaka içermek zorundadır. Tabi ki route kurallarını değiştirmediysek smiley

Son olarak yazdığımız filter'ın application içerisinde aktifleşmesi için register olması gerekir. Bunun için Global.Asax'ın içindeki RegisterGlobalFilters metoduna aşağıdaki kod parçası eklenmelidir;

filters.Add(new ExceptionHandlerFilter());

MVC Exception Handling

Artık projemiz hataları yakalayarak, dost canlısı hata mesajları verebilecek hale geldi laugh Hata Fırlat linkine tıkandığında karşılaşmamız gereken yeni manzara aşağıdaki gibi olmalıdır;

 

Üzgünüm :( Bir Hata Oluştu!

 

Bir sonraki makalemde görüşmek üzere, herkese esenlikler dilerim :)
Teşekkürler faydalı bir yazı.
Yorum Bırak

Facebook
Son Yorumlar