آموزش ASP.NET MVC5 – فصل۱ – بخش۲
آموزش ASP.NET MVC5 - فصل1 - بخش2 : در این مقاله شرایط اکشن بودن یک تابع را بررسی می کنیم، نحوه تغییر نام یک اکشن، تعریف خروجی رشته (string) برای اکشن، ریدایرکت از اکشنی به اکشن دیگر، ارسال پارامتر ورودی بهنگام ریدایرکت اکشن، معرفی و استفاده از متغیر TempData را در MVC آموزش خواهیم داد.

 آموزش MVC »»» جلسه اول »»» قسمت دوم 

 

در مقاله پیشین با معماری قوی MVC آشنا شدیم و مفهوم کنترولر و اکشن را یاد گرفتیم و آنها را با پارامترهای ورودی عددی (INT) و رشته ای (String) فراخوانی کردیم.

در این مقاله قصد داریم اکشن در MVC را بیشتر مورد بررسی و تحلیل قرار دهیم و مثال های دیگری در این زمینه مشاهده کنیم.

 

شرایط اکشن بودن تابعی در کنترولر

 

تعریف Access Modifier:

لزوما هر تابعی در کنترولر ، اکشن نیست . بعنوان مثال اگر Access Modifier تابع را private یا protected یا internal تعریف کنیم آن تابع دیگر اکشن نیست . مانند توابع زیر :

 
private void NonAction1()
{
    // Do Something…
}
protected void NonAction2()
{
    // Do Something…
}
internal void NonAction3()
{
    // Do Something…
}
protected internal void NonAction4()
{
    // Do Something…
}

 

تعریف اتریبیوت NonAction:

ممکنه گاهی خود تابع اکشن باشد و public باشد ولی در بالای آن ، attribute NonAction تعریف کنیم . بنابراین آن تابع هم اکشن نیست . مانند تابع زیر :

 
[System.Web.Mvc.NonAction]
public void NonAction5()
{
    // Do Something…
}

نکته کلی : تابعی اکشن است که اولا public باشد و دوما اتریبیوت NonAction هم نداشته باشد .

 

تغییر نام اکشن :

اگر بخواهیم نام اکشن را توسط اتریبیوت تغییر دهیم داریم :

 
[System.Web.Mvc.ActionName(“SafariAction”)]
public void Learn1100()
{
    // Do Something…
}

از این پس نام اکشن Learn1100 به SafariAction تغییر کرده است . مفهوم Routing یا Mapping نیز همین است . برای اطلاعات بیشتر به وب سایت asp.net مراجعه شود .

در بخش بالا دیدیم که چگونه می توان یک تابعی را به اکشن تبدیل کرد و یا تابعی را از حالت اکشن بودن خارج کرد و نیز چگونه نام اکشن را تغییر دهیم . در بخش بعدی می خواهیم خروجی رشته را برای یک اکشن تعریف کنیم.

 

خروجی رشته (string) برای اکشن (action)

 

تعریف string بجای void:

در این بخش قصد داریم برای اکشن ها خروجی رشته تعریف کنیم . پس دیگر قبل از نام تابع void نداریم و string مینویسیم :

 
public string Learn1110()
{
    return ("Mohtava.info Website is provided by Safari");
}

 

تعریف ContentResult بعنوان خروجی اکشن:

توصیه : برای تعریف خروجی رشته بهتر است نوع خروجی را string نگذاریم و System.Web.Mvc.ContentResult قرار دهیم :

 
public System.Web.Mvc.ContentResult Learn1120()
{
    return (Content("Mohtava.info Website is provided by Safari"));
}

خروجی هر دو اکشن یکی است . اگر مطمئن باشیم خروجی تابع ، رشته است میتوان از مثال فوق استفاده کرد وگرنه در صورتی که خروجی تابع مشخصا رشته نباشد یعنی شاید نوع دیگری باشد باید خروجی اکشن را بصورت System.Web.Mvc.ActionResult تعریف کنیم .

 

تگ html بعنوان خروجی اکشن:

در ضمن می توانیم در رشته خروجی تگ html نیز بنویسیم :

 
public System.Web.Mvc.ContentResult Learn1140()
{
    return (Content("EhsanSafari.com"));
}

پیام خطایی نمی دهد ولی از لحاظ امنیتی وب سایت را دچار تهدید می کند . برای جلوگیری از این مشکل امنیتی باید از Server.HtmlEncode استفاده کنیم :

 
public System.Web.Mvc.ContentResult Learn1150()
{
string strContent =
    Server.HtmlEncode("EhsanSafari.com");
return (Content(strContent));
}

شایان ذکر است که HtmlEncode مختص MVC نیست . بلکه در ASP.NET webform نیز وجود داشت.

در بخش بعدی بیان می کنیم که چگونه می توان از یک اکشن به اکشن دیگری ریدایرکت کنیم (مانند Response.Redirect که در webform وجود داشت).

 

ریدایرکت از اکشنی به اکشن دیگر

 

استفاده از RedirectToAction:

اگر بخواهیم به یک اکشن در کنترولر جاری برویم فقط لازم است نام اکشن را بنویسیم : 

RedirectToAction(actionName: "Action1")

ولی اگر اکشن مقصد در کنترولر دیگری باشد باید نام کنترولر را نیز بنویسیم :

RedirectToAction(controllerName: "Home", actionName: "Action2")

مثال ریدایرکت اکشن:

اکشن کلی بصورت زیر است :

 
public System.Web.Mvc.ActionResult Learn1160(int id)
{
    switch (id)
    {
        case 1:
        {          
            return (RedirectToAction(actionName: "Action1"));
        }
        case 2:
        {
            // Solution (1)
            // ی در همین کنترلر برویم Action اگر بخواهیم به
            return (RedirectToAction(actionName: "Action2"));
            // /Solution (1)
            // Solution (2)
            // ی در کنترلر دیگری برویم Action اگر بخواهیم به
            return (RedirectToAction(actionName: "Action2", controllerName: "Home"));
            // /Solution (2)
            // Solution (3)
            return (RedirectToAction(controllerName: "Home", actionName: "Action2"));
            // /Solution (3)
        }
        default:
        {
            string strContent = "Id value is not valid!";
            return (Content(strContent));
        }
    }
}

در اکشن فوق id ورودی را بررسی می کنیم . با شرایطی خاص به Action1 میرویم و با شرایطی دیگر به Action2 .

 

ریدایرکت اکشن بدون ذکر نام پارامتر:

میتوانستیم دستور فوق را بدون ذکر نام پارامتر بنویسیم (بصورت زیر) :

RedirectToAction("Home","Action2")

پیش فرض تابع ، اولین پارامتر ActionName است و دومی ControllerName . ولی اگر نام پارامترها را هم بنویسیم بهتر است . چرا که می توانیم جای آن دو را با هم جابجا کنیم .

 

کاربرد دستور RedirectPermanent برای ریدایرکت:

علاوه بر دستور RedirectToAction دستور دیگری داریم بنام RedirectPermanent که در مبحث سئو کاربرد دارد . برای جا افتادن مطلب به مثال زیر دقت کنید : فرض کنید یک اکشن ای داریم بنام AboutUs که مثلا ۶ ماه است که طراحی شده و تمام موتورهای جستجو آنرا ایندکس کرده اند . اکنون تصمیم گرفته ایم نام آنرا تغییر دهیم به نام About . برای اینکه مثلا گوگل صفحه قبلی من را گم نکند باید یک اکشنی بسازیم بنام About و در اکشن قبلی یعنی AboutUs دستور زیر را بنویسیم تا هر وقت ربات های جستجوی گوگل به این اکشن رسیدند اتوماتیک و برای همیشه به اکشن About ریدایرکت شوند :

 
[System.Web.Mvc.HttpGet]
public System.Web.Mvc.ActionResult AboutUs()
    {
        return (RedirectPermanent(url: "About"));
    }
}

در بخش بعد میخواهیم وقتی به اکشنی ریدایرکت میکنیم به آن اکشن پارامتر نیز ارسال کنیم .

 

 

ارسال پارامتر ورودی بهنگام ریدایرکت اکشن

 

پارامتر ورودی در اکشن مقصد:

اگر اکشن مقصد (اکشنی که میخواهیم به آن ریدایرکت شویم) دارای پارامتر ورودی باشد باید بصورت زیر عمل کنیم :

اکشن ما در این مثال دارای دو پارامتر firstNumber و secondNumber است . برای ریدایرکت شدن به این اکشن باید از anonymous object استفاده کنیم .

اینگونه تعریف میشود :

routeValues: new { param1 = x1 , param2 = x2 }

اکشن مبدا و مقصد برای ریدایرکت:

پس اکشن مبدا ما بصورت زیر تعریف می شود :

 
public System.Web.Mvc.ActionResult Learn1170()
{     
    return (RedirectToAction(actionName: "Action3",
        routeValues: new { firstNumber = 10, secondNumber = 20 }));
}

و اکشن مقصد نیز بصورت زیر است :

 
public System.Web.Mvc.ActionResult Action3(int firstNumber, int secondNumber)
{
    string strResult =
        string.Format("First Number: {0}, Second Number: {1}",
        firstNumber, secondNumber);
    return (Content(strResult));
}

نکته : اگر هنگام ریدایرکت شدن به اکشن مقصد دقیقا تعداد پارامترها و نام آنها مشخص نباشد(بعنوان مثال بخواهیم از اکشن های مختلف ، اکشن مقصد را با پارامترهای مختلف صدا بزنیم) باید از متغیر TempData استفاده کنیم .  در  بخش بعد با TempData آشنا خواهیم شد.

 

 

معرفی و استفاده از TempData در MVC

 

کاربرد متغیر TempData:

در بخش قبل ، نحوه ریدایرکت به اکشن بهمراه ارسال پارامتر را یاد گرفتیم . با توجه به سناریوی گفته شده در بخش نهایی از این مقاله میخواهیم پارامترهای مختلفی را با نام های گوناگون به اکشن مقصد بفرستیم . 

TempData  مانند Session در ASP.NET webform عمل میکند . در اکشن مبدا داریم :

 
public System.Web.Mvc.ActionResult Learn1180()
{
    TempData[“MyNumber”] = 10;
    return (RedirectToAction(actionName: "Action4"));
}

در اکشن Learn1180 اکشن مقصد را با پارامتر MyNumber صدا زدیم و ریدایرکت شدیم . ممکن است در اکشنی دیگر (Learn1190 ) بخواهیم اکشن مقصد را با متغیر دیگری مانند MyName صدا بزنیم :

 
public System.Web.Mvc.ActionResult Learn1190()
{
    TempData[“MyName”] = "Ehsan Safari";
    return (RedirectToAction(actionName: "Action4"));
}

و در اکشن مقصد (Action4) پارامترهای فوق را بررسی میکنیم . اگر خالی نبودند آنرا چاپ میکنیم :

 
public System.Web.Mvc.ActionResult Action4()
{
    string strResult = string.Empty;
    if (TempData[“MyNumber”] != null)
    {
        int intMyNumber =
            System.Convert.ToInt32(TempData[“MyNumber”]);
        strResult =
            string.Format("My Number is {0}", intMyNumber);
    }
    if (TempData[“MyName”] != null)
    {
        string strMyName =
            TempData[“MyName”].ToString();
        strResult =
            string.Format("My Name is {0}", strMyName);
    }
    return (Content(strResult));
}

نکته : متغیر TempData عمر محدودی دارد یعنی مثلا متغیر MyNumber تا وقتی که خروجی به کاربر نمایش داده نشده است زنده می ماند ! بعد از آن null می شود.

 

نگهداری مقدار TempData توسط دستور Keep :

برای نگهداری مقدار قبلی tempdata از دستور keep استفاده میکنیم . برای روشن شدن مطلب به مثال زیر توجه کنید :

دو اکشن به نامهای Learn 1190 و Learn1200 داریم که در اولی از keep استفاده نکردیم :

 
public System.Web.Mvc.ContentResult Learn1190()
{
    if (TempData[“MyNumber”] == null)
    {
        TempData[“MyNumber”] = 10;
    }
    else
    {
        TempData[“MyNumber”] =
            (int)TempData[“MyNumber”] + 1;
    }
    return (Content(TempData[“MyNumber”].ToString()));
}

با هر بار refresh شدن صحه مروگر مقدار MyNumber برابر با null می شود و دوباره مقدار ۱۰ میگیرد . در اکشن دومی یعنی Learn1200 از دستور keep استفاده کرده ایم :

 
public System.Web.Mvc.ContentResult Learn1200()
{
    if (TempData[“MyNumber”] == null)
    {
        TempData[“MyNumber”] = 10;
    }
    else
    {
        TempData[“MyNumber”] =
            (int)TempData[“MyNumber”] + 1;
    }
    //TempData.Keep();
    TempData.Keep("MyNumber");
    return (Content(TempData[“MyNumber”].ToString()));
}

بنابراین با هر بار بارگذاری صفحه مقدار قبلی در MyNumber می ماند و هر بار یکواحد به مقدار قبلیش اضافه می شود .

 نکته : می توان بعنوان مثال یک متغیر بنام age در اکشنی تعریف کنیم و آنرا keep کنیم و در اکشن دیگری از آن استفاده کنیم . به مثال زیر توجه کنید :

در اکشن Learn1210 متغیر age  را  در TempData تعریف کرده و آنرا keep میکنیم :

 
public System.Web.Mvc.ContentResult Learn1210()
{
    TempData[“Age”] = 10;
    TempData.Keep("Age");
        return (Content(TempData[“Age”].ToString()));
}

و در اکشن دوم Learn1220 آن متغیر نگهداری شده یعنی Age را چاپ میکنیم :

 
public System.Web.Mvc.ContentResult Learn1220()
{
    if (TempData[“Age”] == null)
    {
        return (Content("Undefined!"));
    }
    else
    {
        return (Content(TempData[“Age”].ToString()));
    }
}

در بار اولی که این اکشن اجرا می شود شرط if برابر false است و اجرا نمیشود و به else  میرود . در بار دوم به بعد چون آن متغیر را keep نکرده ایم مقدارش null میشود و شرط if برابر true میشود . برای کسب اطلاعات بیشتر به وب سایت asp.net مراجعه شود .

بخش سوم از جلسه اول آموزش MVC را مطالعه کنید.


برچسب‌ها:

Controllerfunctionاتریبیوت NonActionانواع تابع در کنترولرتابعتغییر نام اکشنخروجی ContentResultدستور Keepدستور RedirectPermanentدستور RedirectToActionریدایرکت اکشنکنترولرمتغیر TempData



دیدگاه‌ها :