علی شکرالهی
بنیانگذار توسینسو و توسعه دهنده

آموزش دریافت درخواست های Ajax و رد سایر درخواست ها در ASP.NET MVC

چگونه درخواست های Ajax را در ASP.NET MVC دریافت کنیم؟ به عنوان اولین مقاله قصد دارم که یک سری مقاله رو آغاز کنم با عنوان TipTip که در هر سری ، یک یا چند نکته در زمینه ی وب رو بررسی میکنم.در ASP.NET MVC ، مفهومی با عنوان Action Filters وجود داره که این امکان رو به ما میده تا بتونیم عملیات فراخوانی Action ها رو کنترل کنیم .Attribute یی با نام ActionFilterAttribute وجود داره که دارای چهارتابع به شکل زیر هست:

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران
public virtual void OnActionExecuting(ActionExecutingContext filterContext)
{
}

public virtual void OnActionExecuted(ActionExecutedContext filterContext)
{
}

public virtual void OnResultExecuting(ResultExecutingContext filterContext)
{
}

public virtual void OnResultExecuted(ResultExecutedContext filterContext)
{
}


OnActionExecuting ، قبل از اجرای Action فراخوانی می شه و OnActionExecuted بعد از فراخوانی اون .همینطور تابع OnResultExecuting ، قبل از اجرای تابع Execute مربوط به Result فراخوانی میشه ، و OnResultExecuted بعد از اجرای آن.فرض کنید که ما کنترلری با نام Home داریم که داخل اون یک Action به نام Test تعریف شده:

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


یعنی ما می تونیم اکشن Test رو از طریق مرورگر به شکل زیر فراخونی کنیم:

http://domain.com/Home/Test


وقتی این درخواست به وب سرور می رسه ، بعد از اینکه عملیات روتینگ انجام شد ، اکشن Test فراخونی میشه ، عملیات داخلیش انجام شده و بعد یک خروجی از نوع ActionResult رو برمیگردونه .کاری که ما قصد داریم انجام بدیم این هست که تنها درخواستهایی رو بپذیریم که بصورت Ajaxیی ارسال شده باشن. یعنی در Header ارسالی کلید X-Requested-With با مقدار XMLHttpRequest وجود داشته باشه .برای اینکار یک کلاس جدید با نام AjaxRequest ایجاد میکنیم که از ActionFilterAttribute ارث بری کنه :

public class AjaxRequest : ActionFilterAttribute
{
    
}


چون ما میخوایم قبل از اجرای Action بررسیمون رو انجام بدیم ، پس تابع OnActionExecuting رو Override میکنیم و کد زیر رو داخلش قرار میدیم:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    if (filterContext.HttpContext.Request.IsAjaxRequest()) return;

    filterContext.Result = new ContentResult();
}


کاری که کد بالا انجام میده ، قبل از فراخوانیه اکشن ، بررسی میکنه که آیا این درخواست یک درخواست Ajax یی هست یا نه .در صورتی که باشه ، کارش رو ادامه میده ، در غیر این صورت پراپرتی Result مربوط به filterContext رو برابر با ContentResult میکنه .این کار باعث میشه ، تا فراخوانی اکشن Test متوقف بشه . چون بعد از پایان تابع OnActionExecuting بررسی میشه که آیا Result مقداری گرفته یا نه. در صورتی که مقداری گرفته باشه ، صرفا همون Result رو اجرا میکنه و دیگه اکشن فراخوانی نمیشه .در اینجا من یک ContentResult رو ست کردم ، بدین معنی که یک صفحه ی خالی براش ارسال میشه ، شما ممکنه بخواید Exception یی رو throw کنید . روش ها متفاوت است .کد نهایی ما به شکل زیر در میاد:

public class AjaxRequest : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest()) return;

        filterContext.Result = new ContentResult();
    }
}


حال ما میتونیم این Filter رو بروی اکشنمون قرار بدیم. به شکل زیر:

public class HomeController : Controller
{
    [AjaxRequest]
    public ActionResult Test()
    {
           return Content("Hello World");
    }
}

حالا ، اگه درخواستی بصورت مستقیم از طریق مرورگر برای Test ارسال بشه ، صرفا صفحه ای خالی دیده میشه . ولی اگه درخواست بصورت Ajaxیی صورت بگیره متن Hello World برای کلاینت ارسال میشه . با آرزوی موفقیت...


علی شکرالهی
علی شکرالهی

بنیانگذار توسینسو و توسعه دهنده

علی شکرالهی، بنیانگذار TOSINSO ، توسعه دهنده وب و برنامه نویس موبایل، مهندسی نرم افزار از دانشگاه آزاد اسلامی واحد کرج ، بیش از 15 سال سابقه ی فعالیت های حرفه ای و آموزشی

نظرات