ASP.NET MVC'de Genel Hata Yönetimi

Yazdığımız projelerde kod hatalarının bulunabilme ihtimali her zaman vardır. Bu hatalar tamamen bizden kaynaklı olabilir veya tahmin edemediğimiz durumlarda ortaya çıkabilir. Bu gibi durumlarda hatanın kaynağının direkt olarak son kullanıcıya gösterilmesi hem görsellik açısından güzel bir durum değildir, hem de projemizdeki bazı kodların son kullanıcıya gösterilmesine yani güvenlik zaafiyetine yol açabilir. Mesela kullanıcı sitemizde var olmayan bir adrese gitmek isteyebilir. Bu nedenle projede meydana gelebilecek herhangi bir hatayı merkezi olarak yönetebilmemiz gerekmektedir. ASP.NET bu amaçla etkili bir hata yönetimi (error handling) sunmaktadır. Uygulamamızda tüm request ve response'lerin yönetildiği, bunlara ait event'ların yakalandığı Global.asax dosyasında uygulamanın herhangi bir bölümünde herhangi bir kaynaktan dolayı meydana gelen hataların yakalanacağı Application_Error() metodunu kullanabiliriz. Bu metodu kullanarak herhangi bir hata meydana geldiğinde ASP.NET'in tipik hata sayfalarını göstermek yerine özel hata sayfalarımızı kullanıcılara gösterebiliriz. Bu sayede uygulamada oluşan hataları veritabanına yazdırabilir veya kendimize mail olarak gönderebiliriz.

protected void Application_Error()
{
    var exception = Server.GetLastError(); //Oluşan hatayı değişkene atadık.
    //Eğer hata kaydı (log) tutulacak ise gerekli kodlar buraya.
    var httpException = exception as HttpException;
    Response.Clear();
    Server.ClearError(); //Sunucudaki hatayı temizledik.
    Response.TrySkipIisCustomErrors = true//IIS'in tipik hata sayfalarını görmezden geldik.
    var routeData = new RouteData();
    routeData.Values["controller"] = "Error"//Hata mesajlarını yöneteceğimiz Controller ismi
    routeData.Values["action"] = "Index"//Controller içindeki default Action ismi
    routeData.Values["exception"] = exception;
    Response.StatusCode = 500;

    if (httpException != null)
    {
        Response.StatusCode = httpException.GetHttpCode();

        switch (Response.StatusCode)
        {
            case 403: //Eğer 403 hatası meydana gelmiş ise Http403 Action'ı devreye girecek.
                routeData.Values["action"] = "Http403";
                break;

            case 404: //Eğer 404 hatası meydana gelmiş ise Http404 Action'ı devreye girecek.
                routeData.Values["action"] = "Http404";
                break;
        }
    }

    IController errorsController = new Controllers.ErrorController();
    var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
    errorsController.Execute(rc);
}

Şimdi yakalanan hataları kullanıcılara gösterebilmemiz için Model, Controller ve View'ı oluşturalım.

ErrorModel

public class ErrorModel
{
    public string ErrorTitle { getset; }
    public Exception ExceptionDetail { getset; }
}

ErrorController

public ViewResult Index(Exception exception)
{
    return View("Error"new ErrorModel { ErrorTitle = "Bir Hata Meydana Geldi", ExceptionDetail = exception });
}

public ViewResult Http404()
{
    return View("Error"new ErrorModel { ErrorTitle = "Sayfa Bulunamadı" });
}

public ViewResult Http403()
{
    return View("Error"new ErrorModel { ErrorTitle = "Yasaklı içerik" });
}

Ve son olarak View dosyamız

@model MvcApplication1.Models.ErrorModel
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = Model.ErrorTitle;
}

@if (Response.StatusCode == 404)
{
    <img src="/content/images/error/404.png" alt="Sayfa Bulunamadı" />
}
else
{
    if (Model.ExceptionDetail != null)
    {
        @Model.ExceptionDetail.Message
    }
}

YORUMLAR (11)

  1. Yavuz Ağca
    Yavuz Ağca

    Merhaba,Elinize sağlık güzel bir makale olmuş fakat sormak istediğim bir kaç sorum var şimdiden teşekkürler;

    1- projeme kodları ekledim (Global .asax.cs içine Application Error metodunu) fakat olmayan bir url isteği yaptığımda case 404 giriyor sonra errorsController.Execute(rc); satırında "Only one 'model' statement is allowed in a file." hatasını veriyor errorController içeriside sizin makalede yaptığınız gibi

    2 - benim şu şekilde bir url yapım var /view/sayfa url/dil (ürün/beyaz-dikenler/TR/) bu urlde dili veya sayfa url sildiğimde httpException nesnesi null gelmiyor ama view isminde bir değişiklik yaptığımda httpException null dönüyorsizce neden kaynaklana bilir.
    • Mehmet YAYLACI
      Mehmet YAYLACI
      Merhaba. Öncelikle mail sunucusunda problem yaşamam nedeniyle mesajınızı yeni gördüm. Kusura bakmayın. Hatanıza gelince bir View'da sadece 1 model kullanabileceğiniz için hatayı alıyorsunuz. Tabi proje dosyalarını görmeden maalesef tam bir cevap veremeyeceğim. Kolay gelsin.
  2. Remzi Altın
    Remzi Altın
    Hocam bende bu hatayı verdi neden olabilir? Sorry, an error occurred while processing your request.
    • Mehmet YAYLACI
      Mehmet YAYLACI

      Web.config dosyanızda

      <system.web>

      düğümü altında

      <compilation debug="true" />
      <customErrors mode="Off" />
      ayarlarını uygularsanız sorununuzun ne olduğunu daha kolay anlayabilirsiniz.
  3. Oğuzhan SARI
    Oğuzhan SARI

    Merhaba, Bilgiler için teşekkürler. Bende şöyle bir sıkıntı mevcut.

    localhost:888/Index/olmayansayfa

    yazdığımda hata sayfası sorunsuz geliyor. Fakat

    localhost:888/olmayansayfa
    şeklinde yazdığımda hata sayfası kaynak kodu text metin olarak gözüküyor. Daha doğrusu controller altında action yoksa hata sayfası normal gözüküyor. Fakat controller veya controller ile action olmayan bir linkte hata sayfası text metin olarak gözüküyor. Çözümü ne olabilir?
  4. Ayşen Sonkunduracı
    Ayşen Sonkunduracı
    Hakikaten çok güzel anlatmışınız. Ne zamandır aradığım bir konu idi çok makbule geçti teşekkürler. :)
  5. Ahmet TÜRKÖZ
    Ahmet TÜRKÖZ
    Hocam öncelikle paylaşımınız için teşşekürler. Bende Oğuzhan SARI arkadaşımızın söylemeye çalıştığı sorun ile karşılaştım. Eğer ana dizinden sonra olmayan bir controller şeklinde bir ifade yazarsak örn: localhost/olmayanbircontroller browserda sayfanın kaynak kodunu açıyor.Routeconfig dosyasında bir kontrol gerekiyor sanki ama bende başaramadım. Debug edildiğinde tespit şu şekilde= routeData.Values=exceptions={"The controller for path '/Homekjhk' was not found or does not implement IController."} olduğunda gerçekliyor.
  6. Muhammet
    Muhammet
    Bende Ahmet Türköz ve Oğuzhan Sarı arkadaşımızın yaşadığı sorunu yaşıyorum çözüm bulan varmı ?

YORUM FORMU