PDA

View Full Version : طریقه ی استفاده از فیلتر HandleError



alishokr
چهارشنبه 26 آبان 1389, 23:12 عصر
با عرض سلام خدمت دوستان .
یکی از مسائلی که در برنامه ها مطرح میشه ، طریقه ی Handle کردن exception ها هست.
گاهی ممکنه ما بخوایم استثنائاتی که در برنامه رخ میده رو در جایی log کنیم و کاربر رو به صفحه ی مناسبی ببریم ...(Ooo0o0ops pages) .
یکی از راه های موجود در ASP.NET Mvc استفاده از فیلتری با نام HandleError هست که بروی Action یا Controller موردنظر قرار میگیره تا این مسئله رو برای ما حل کنه .


نکته: دوستان کارهایی که در بالا انجام میشه متاسفانه در حالت local جواب نمیده، حالا چرا نمیدونم :-??
البته اگه یه Custom HandleError بنویسید مشکل حل میشه که انشاء الله در مقاله بعدی طریقه ی پیاده سازی این کار رو توضیح میدم .



در ابتدا پروژه ای از نوعASP.NET Mvc 2 Empty Web Application ایجاد کنید .
حال از پنجره ی Solution Explorer ، بروی Controllers کلیک راست کرده و از منوی Add بروی Controller کلیک کنید .
در پنجره ای که نمایش داده میشه نامی برای Controller انتخاب کنید (دقت کنید که پسوند Controller میبایست برای نام وجود داشته باشه. یعنی اگه بناست که نام Home رو برای Controller انتخاب کنید باید در کادر بنویسید HomeController) .
خوب حالا در Code Editor ، فیلتر HandleError رو به Controller اضافه کنید. بصورت زیر:


[HandleError]
public class DefaultController : Controller


یه موضوعی رو برای دوستانی که با Mvc آشنایی کاملی ندارن بگم که Filter در واقع همون Attribute های خودمون هستن . بهشون میگیم Filter چون در سایر فریم ورک های موجود مثل Ruby on rails هم به این نام خونده میشن.


و باز نکته ای دیگر: HandleError میتونه بروی Action ها هم قرار بگیره .
نکته ای دیگر : منظور از Action ، به معنای ساده همون متدهای ما میشه که در داخل کلاس Controller تعریف میشن .


خوب حالا یکسری از پراپرتی های HandleError رو در زیر توضیح میدم :


ExceptionType:
ما میتونیم بگیم که در این controller در صورتی که خطایی از نوع خاصی رخ داد ، اونوقت خطا رو Handle کن .
یعنی چی ، یعنی مثلا ما میتونیم بگیم ExceptionType=typeof(ArgumentException) . این مسئله باعث میشه تا تنها زمانی خطای ما توست HandleError کنترل بشه که exception رخ داده از نوع ArgumentException باشه .
در صورتی که مقداری به ExceptionType داده نشه ، بطور پیش فرض از نوع Exception میشه که به عبارتی تمام خطاها رو پوشش میده . (البته بطور پیش فرض در طراحی ASP.NET Mvc در صورتی که ThreadAbortException رخ بده ]مواقعی که ما از Response.Redirect استفاده کنیم[ ، این استثنا نادیده گرفته میشه ) .


View:
نام View یی که میخوایم برای نمایش اطلاعات به کاربر استفاده بشه .
در صورت تعیین نامی برای View (مثلا ErrorMessage)مسیرهای زیر برای پیدا کردن View مورد نظر بررسی میشه :



~/Views/controllerName/ErrorMessage.aspx
~/Views/controllerName/ErrorMessage.ascx
~/Views/Shared/ErrorMessage.aspx
~/Views/Shared/ErrorMessage.ascx


حالا اگه نامی رو برای View تعیین نکنیم ، بطور پیش فرض نام Error میگیره . یعنی در مسیر های بالا بجای ErrorMessage بدنبال Error میگرده .
نکته: در قسمت بالا دقت بشه که controllerName نام controller یی هست که در اون خطا رخ داده .


Master:
نام MasterPage یی که مدنظر داریم برای View تعیین بشه .


Order:
جهت تعیین اولویت برای تقدم یا تاخر در اجرا در بین سایر HandleError های تعیین شده .


چون ما بطور کلی میخوایم برای سایتمون یک صفحه در نظر بگیریم برای نمایش خطا، در پنجره ی Solution Explorer در مسیر Views/Shared یک View جدید با نام Error اضافه میکنیم .
بعد از ساخته شدن View ، اگه دقت کنید مدلی که در Page Directive صفحه تعیین شده از نوع dynamic هست .
فیلتر HandleError ، مدلی که برای صفحه Error بطور پیش فرض در نظر میگیره HandleErrorInfo هست .
پس برای اینکه ما به پراپرتی های HandleErrorInfo دسترسی داشته باشیم ، بجای dynamic بنویسید HandleErrorInfo .(البته اگر این کار رو انجام ندید هم میشه از پراپرتی های HandleErrorInfo استفاده کرد ، ما به این دلیل نوع مدل رو عوض کردیم تا Intellisenseداشته باشیم .)
حالا در داخل body یک تگ div تعریف کنید و کد زیر رو بنویسید :


<p>Message: <%: Model.Exception.Message %></p>
<p>Stack Trace: <%: Model.Exception.StackTrace %></p>
<%= Html.ActionUrl(“Return”,Model.ActionName,Model .ControllerName) %>


حالا میخوایم تست کنیم و ببینیم که آیا در صورت بروز خطا این صفحه نمایش داده میشه یا خیر .
به Controllerیی که در ابتدا ساختید برگردید و در داخل متد(Action) با نام Index کد زیر رو قرار بدید :


public ActionResult Index()
{
throw new ArgumentException(“I raised an custom exception”);
}


همونطور که در بالا هم گفتم :

کارهایی که در بالا انجام میشه متاسفانه در حالت local جواب نمیده، حالا چرا نمیدونم :-??
البته اگه یه Custom HandleError بنویسید مشکل حل میشه که انشاء الله در مقاله بعدی طریقه ی پیاده سازی این کار رو توضیح میدم .



با آرزوی موفقیت ...