نمایش نتایج 1 تا 2 از 2

نام تاپیک: طریقه ی ایجاد Custom ErrorHandle در ASP.NET MVC

  1. #1
    کاربر تازه وارد آواتار alishokr
    تاریخ عضویت
    شهریور 1389
    محل زندگی
    کرج
    پست
    48

    طریقه ی ایجاد Custom ErrorHandle در ASP.NET MVC

    در پستی با عنوان طریقه ی استفاده از فیلتر HandleError استفاده از فیلتر HandleError رو بررسی کردیم .
    در روش قبل ، امکان Log کردن خطاها وجود نداشت . در این پست قصد داریم طریقه ی پیاده سازی یک فیلتر Custom جهت کنترل exception ها و Log کردن اون ها رو بررسی کنیم .
    ابتدا یک کلاس با نام CustomErrorHandle بسازید و و از کلاس FilterAttribute و اینترفیس IExceptionFilter ارث بری کنید و متد OnException اینترفیس رو پیاده سازی کنید. بشکل زیر:

    public classCustomErrorHandle : FilterAttribute, IExceptionFilter






    {


    publicvoid OnException(ExceptionContext filterContext)
    {
     
     
    }
    }




    حالا ما میتونیم در داخل متد OnException بگیم که چطور خطا رو کنترل کنه .
    کاری که ما میخوایم بکنیم این هست که :
    ابتدا خطا رو در EventLog ویندوز ثبت کنیم
    بعد صفحه ای رو با پیغام "An Exception occured" نمایش داده و در اون صفحه لینک بازگشت به صفحه ای که خطا در اون اتفاق افتاده رو قرار بدیم .
    برای این کار در Solution Explorer ، در شاخه ی Views/Shared ، صفحه ای جدید با نام Message اضافه میکنیم.(در این مثال من از ASP.NET MVC 3 استفاده میکنم، شما میتونید از MVC2 استفاده کنید. اصل تفاوت در استفاده از Razor هست .)


    حالا در شاخه ی Models ، کلاس جدیدی با نام Message اضافه کرده و پراپرتی های زیر رو به این کلاس اضافه میکنیم :




    publicclassMessage






    {


    publicstring MessageContent { get; set; }


    publicstring ActionName { get; set; }


    publicstring ControllerName { get; set; }


    publicstring AreaName { get; set; }
    }




    حالا صفحه ی Message رو بازکرده و کد زیر رو به صفحه اضافه کنید :

    Razor view engine:
    @model Mvc3.Models.Message


    ASPX view engine:
    <%@ Page Language="C#‎‎‎‎" Inherits="System.Web.Mvc.ViewPage<Mvc3.Models.Message>" %>



    دقت کنید ، بجای Mvc3 شما میبایست نام پروژه خودتون رو قرار بدید .
    حالا در قسمت Body کد زیر رو وارد کنید:

    <div>
    <p>Message: @Model.MessageContent</p>
    @Html.ActionLink("Return", Model.ActionName,
    Model.ControllerName,
    new { area = Model.AreaName },
    null);
    </div>




    حالا میمونه اصل کد ، که میبایست در داخل متد OnException قرار بدیم:

    if (filterContext.ExceptionHandled) //1
    return;
    var actionName = filterContext.RouteData.Values["action"].ToString();//2
    var controllerName = filterContext.RouteData.Values["controller"].ToString();//2
    var areaName = filterContext.RouteData.DataTokens["area"] == null
    ? null
    : filterContext.RouteData.DataTokens["area"].ToString(); //3

    var eLog = new EventLog(string.Empty, ".") //4
    {Source = "Application"};
    eLog.WriteEntry(filterContext.Exception.Message, EventLogEntryType.Error);


    filterContext.ExceptionHandled = true; //5
    filterContext.Result = new ViewResult //6
    {
    ViewName = "Message",
    ViewData = new ViewDataDictionary<Message>(new Message {
    ActionName = actionName,
    ControllerName = controllerName,
    AreaName = areaName,
    MessageContent = "An Exception Occured"})
    };
    filterContext.RequestContext.HttpContext.Response. ClearContent();//7

    در آخر هر خط comment یی با یک شماره مشخص شده که در زیر در مورد هرکدوم توضیح میدم.
    1. در این خط ما بررسی میکنیم که اگر exception توسط یک فیلتر دیگه Handle شده ، دیگه بررسی نکنه.
    2. از مجموعه ی Values که در پراپرتی RouteData قرار داره مقدار action و controller رو بدست میاریم .
    3. در صورتی که ما در پروژه مون از Area استفاده کرده باشیم ، نام Area در داخل DataTokens نگه داری میشه ، نه داخل Values .(همینطور نام Namespace هایی که ما برای route هامون تعیین میکنیم )
    4. این قسمت هم که برای نوشتن خطا در EventLog قرار گرفته. شما میتونید بجای این دو خط ، کدی بنویسید تا بر فرض خطا رو برای ایمیلی ارسال کنه .
    5. در این خط ما ExceptionHandled رو برابر با true قرار میدیم تا سایر فیلترهامون دیگه این خطا رو بررسی نکنن.
    6. مقدار Result یی که میخوایم استفاده بشه رو تعیین میکنیم . در اینجا ما از ViewResult استفاده کردیم تا صفحه ی خطا رو نمایش بدیم . همونطور که در کد مشخص هست ، ما نام ViewName رو برابر با Message دادیم و ViewData رو از نوع Message گرفتیم (چون Model یی که برای صفحه Message انتخاب کردیم از نوع Message بود)
    7. در این خط هم ، Response رو Clear کردیم تا در صورتی که چیزی برای خروجی رفته بود پاک بشه .

    حالا برای تست ، ابتدا در web.config، قسمت customErrors رو قرار داده و mode رو برابر با On میکنیم.

    <customErrors mode=”On” />

    در Controllers یک کنترلر جدید با نام Default اضافه میکنیم .
    در داخل اون دو Action Method با نام Index تعریف میکنیم ، به شکل زیر:

    public ActionResult Index()
    {
    return View();
    }
    [HttpPost]
    public ActionResult Index(string buttonName)
    {
    throw new Exception("exception raised.");
    }

    حالا روی Index راست کلیک کرده و روی Add View کلیک میکنیم .
    بعد از اضافه کردن View ، در داخل تگ Body کد زیر رو قرار میدیم.

    Razor viewEngine:
    @using (Html.BeginForm())
    {


    <inputtype="submit"value="Click me to raise an exception!"/>






    }




    ASPX View engine:

    <% using(Html.BeginForm()) {%>


    <inputtype="submit"value="Click me to raise an exception"/>






    <% } %>






    حالا پروژه رو با CTRL + F5 اجرا میکنیم (یا در فایل web.config ، در قسمت compilation مقدار debug رو برابر با false قرار میدیم .)
    حالا باید گفت ، آیا راه دیگه ای هم وجود داره ؟ بله .
    کلاس Controller متدی داره با نام OnException که میتونیم overrideش کنیم و مثل همین فیلتر عمل میکنه .
    اکثرا مواقعی استفاده میشه که بخواید برای Controllerیی منطق خاصی رو بکار ببرید که با سایر کنترلرهاتون متفاوت هست .
    مثال زیر رو در نظر بگیرید:


    public class DefaultController : Controller
    {
    protected override void OnException(ExceptionContext filterContext)
    {
    // place your logic.

    }
    }

    البته شما میتونید یک کلاس Base تعریف کنید که از Controller ارث بری کنه و با override کردن متد OnException در کلاس Base ، سایر Controller هاتون رو از کلاس Base مشتق کنید و به نتیجه یکسانی برسید .

    اینجا خوبه به یکی از ویژگی های جدید MVC3 اشاره کنم .
    ممکنه شما پروژه ای رو به اتمام رسونده باشید و بخواید همچین روشی رو بروی پروژه تون اعمال کنید . یعنی یک فیلتر برای Handle کردن Exception ها بنویسید و بروی تمام Controller هاتون اعمال کنید .
    مطابق با توضیحات بالا ، در حال حاضر دو روش داریم: یا روی تک تک کنترلرهامون این فیلتر رو اضافه کنیم یا یک کلاس پایه تعریف کنیم و بروی اون فیلتر رو اضافه کنیم و بعد تمام کنترلرهامون رو از اون مشتق کنیم .
    در MVC3 روش جدید وجود داره . در داخل فایل global.asax ، تابع استاتیکی وجود داره با نام RegisterGlobalFilters که میتونیم در داخل اون ، فیلترهایی که بناست بروی تمام کنترلرها اعمال بشه قرار بدیم تا بصورت خودکار به تمامشون اعمال بشه .
    یعنی برای اضافه کردن CustomErrorHandle خودمون ، بصورت زیر عمل میکنیم :

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
    filters.Add(new Infrastructures.CustomErrorHandlerAttribute());
    }


    با آرزوی موفقیت ...
    آخرین ویرایش به وسیله alishokr : جمعه 19 فروردین 1390 در 22:41 عصر

  2. #2
    کاربر دائمی آواتار aserfg
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    Asp+.net
    پست
    617

    نقل قول: طریقه ی ایجاد Custom ErrorHandle در ASP.NET MVC

    دوست عزیز کدهات رو درست کن تا دوستان مشکلی در استفاده نداشته باشن
    با تشکر

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •