تفاوت بین ViewBag، ViewData و TempData در ASP.NET CORE MVC چیست؟
برای این منظور، فریمورک ASP.NET سه ابزار اصلی در اختیار ما قرار داده است: ViewData، ViewBag و TempData. اگرچه هدف نهایی هر سه انتقال داده است، اما تفاوتهای ساختاری و عملکردی مهمی دارند که انتخاب اشتباه آنها میتواند منجر به خطاهای زمان اجرا (Runtime) یا سردرگمی در نگهداری کد شود.
در این مقاله، به بررسی عمیق و مقایسهی این سه مکانیزم میپردازیم.
ViewData چیست؟
ViewData یک شیء دیکشنری (Dictionary) است که از کلاس ViewDataDictionary مشتق شده است. این ابزار از نسخههای اولیه ASP.NET MVC وجود داشته و برای ذخیره دادهها در قالب Key-Value استفاده میشود.
ویژگیهای کلیدی ViewData:
-
ساختار: دادهها را به صورت جفتهای کلید و مقدار (مثلاً string به عنوان کلید و object به عنوان مقدار) ذخیره میکند.
-
Type Casting: از آنجایی که مقادیر به صورت object ذخیره میشوند، هنگام بازخوانی در View، حتماً باید آنها را به نوع داده اصلی خود Cast کنید (مگر اینکه فقط قصد نمایش رشته ساده را داشته باشید).
-
طول عمر (Life Cycle): دادههای ذخیره شده در آن فقط در طول درخواست فعلی (Current Request) معتبر هستند. با تغییر صفحه یا رفرش شدن، این دادهها از بین میروند.
مثال استفاده:
در کنترلر:
public IActionResult Index()
{
ViewData["Greeting"] = "خوش آمدید!";
ViewData["UserCount"] = 150;
return View();
}
در View:
<h2>@ViewData["Greeting"]</h2>
<p>تعداد کاربران: @((int)ViewData["UserCount"])</p> ```
---
## ۲. ViewBag چیست؟
`ViewBag` در واقع یک پوشش (Wrapper) به دور `ViewData` است که در C# 4.0 و با معرفی کلمه کلیدی `dynamic` اضافه شد. این ابزار به شما اجازه میدهد ویژگیها را به صورت داینامیک به یک شیء اضافه کنید.
### ویژگیهای کلیدی ViewBag:
* **ساختار:** از نوع `dynamic` است. به این معنی که نیازی نیست از کلیدهای رشتهای در براکت استفاده کنید؛ در عوض مستقیماً از نقطهگذاری (Dot notation) استفاده میکنید.
* **Type Casting:** بر خلاف ViewData، در اکثر مواقع نیازی به کست کردن دستی ندارد (به دلیل ماهیت داینامیک).
* **ارتباط با ViewData:** جالب است بدانید که `ViewBag` و `ViewData` هر دو به یک منبع داده اشاره میکنند. یعنی اگر در کنترلر بنویسید `ViewBag.Name = "Ali"`, میتوانید در View آن را با `@ViewData["Name"]` بخوانید.
* **طول عمر:** همانند ViewData، فقط برای **درخواست فعلی** زنده میماند.
### مثال استفاده:
در کنترلر:
```csharp
public IActionResult Profile()
{
ViewBag.Title = "پروفایل کاربر";
ViewBag.LastLogin = DateTime.Now;
return View();
}
در View:
<h1>@ViewBag.Title</h1>
<p>آخرین ورود: @ViewBag.LastLogin</p> ```
---
## ۳. TempData چیست؟
`TempData` تفاوت بنیادی با دو مورد قبلی دارد. این ابزار نیز یک دیکشنری است (از نوع `TempDataDictionary`) اما هدف آن ذخیره دادههایی است که باید در **درخواست بعدی (Next Request)** نیز در دسترس باشند.
### ویژگیهای کلیدی TempData:
* **طول عمر:** دادهها را تا زمانی که **خوانده شوند** حفظ میکند. معمولاً برای سناریوی **Redirect** استفاده میشود (مثلاً نمایش پیغام موفقیت پس از ثبتنام و انتقال کاربر به صفحه لاگین).
* **مکانیزم ذخیرهسازی:** به طور پیشفرض، TempData از **Session** یا **Cookie** برای نگهداری دادهها استفاده میکند.
* **قانون یکبار مصرف:** به محض اینکه یک مقدار از TempData خوانده شود، آن مقدار برای حذف در پایان درخواست علامتگذاری میشود.
* **Keep و Peek:** اگر بخواهید دادهها پس از خوانده شدن همچنان باقی بمانند، میتوانید از متدهای `Keep()` یا `Peek()` استفاده کنید.
### مثال استفاده:
در کنترلر (متد اول):
```csharp
public IActionResult SubmitForm()
{
TempData["Message"] = "اطلاعات با موفقیت ثبت شد.";
return RedirectToAction("Confirm");
}
در کنترلر (متد دوم پس از ریدایرکت):
public IActionResult Confirm()
{
// داده هنوز در TempData موجود است
return View();
}
در View:
<div class="alert">
@TempData["Message"]
</div>
مقایسه نهایی در یک نگاه
برای درک بهتر، تفاوتها را در جدول زیر خلاصه کردهایم:
| ویژگی | ViewData | ViewBag | TempData |
| نوع داده | Dictionary (Key-Value) | Dynamic Property | Dictionary (Key-Value) |
| فضای نام | Microsoft.AspNetCore.Mvc | Microsoft.AspNetCore.Mvc | Microsoft.AspNetCore.Mvc |
| نسخه معرفی | MVC 1.0 | MVC 3.0 | MVC 1.0 |
| نیاز به کستینگ | بله (برای انواع پیچیده) | خیر (داینامیک است) | بله |
| طول عمر | فقط درخواست فعلی | فقط درخواست فعلی | تا درخواست بعدی (ریدایرکت) |
| منبع اصلی | ViewDataDictionary | DynamicViewData | TempDataDictionary |
چه زمانی از کدام استفاده کنیم؟ (Best Practices)
به عنوان یک توسعهدهنده حرفهای، باید بدانید که اگرچه این ابزارها مفید هستند، اما استفاده بیش از حد از آنها میتواند کد شما را "کثیف" کند.
-
اولویت با Strongly Typed Views: همیشه سعی کنید از یک ViewModel اختصاصی استفاده کنید. این کار باعث میشود خطاها در زمان کامپایل (Compile-time) مشخص شوند و از قدرت IntelliSense در ویژوال استودیو بهرهمند شوید.
-
استفاده از ViewData/ViewBag: اینها را برای مقادیر کوچک و غیرحساس که جزئی از مدل اصلی صفحه نیستند نگه دارید (مثلاً عنوان صفحه یا لیست گزینههای یک Dropdown ساده).
-
تفاوت سلیقهای: بین ViewData و ViewBag، انتخاب بیشتر سلیقهای است. ViewBag کد را تمیزتر میکند، اما ViewData به دلیل عدم استفاده از dynamic کمی (بسیار ناچیز) پرفورمنس بهتری دارد و خطاهای تایپی در آن مشخصتر هستند.
-
TempData برای پیامهای موقت: از TempData فقط برای سناریوهایی مثل پیغامهای Error یا Success پس از عملگرهای POST و Redirect استفاده کنید.
نکته حرفهای: متدهای Keep و Peek در TempData
اگر در یک View مقدار TempData["User"] را بخوانید، این مقدار در درخواست بعدی پاک میشود.
-
اگر میخواهید مقدار را بخوانید و همچنان آن را برای درخواستهای بعدی حفظ کنید، از TempData.Peek("User") استفاده کنید.
-
اگر مقدار را خواندهاید و حالا تصمیم گرفتهاید آن را نگه دارید، از TempData.Keep("User") استفاده کنید.
جمعبندی
انتخاب بین ViewData ،ViewBag و TempData بستگی به سناریوی شما دارد. اگر میخواهید دادهای را در همان لحظه به View بفرستید، ViewBag یا ViewData (با اولویت ViewModel) مناسب هستند. اما اگر میخواهید کاربر را به صفحه دیگری بفرستید و دادهای را با خود ببرید، TempData تنها گزینه منطقی است.
0 نظر
هنوز نظری برای این مقاله ثبت نشده است.