ViewData is a dictionary object that allows you to pass data from your controller to your view. It's a mechanism for transferring small amounts of data, typically strings or simple objects, between these two layers of your ASP.NET Core MVC application.
ViewData is a property of the ControllerBase class, and it's accessible in the Razor view through the ViewData property. It's implemented as a dictionary with string keys and object values.
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
{
public IActionResult Index()
{
ViewData["PageTitle"] = "Welcome to Our Site";
ViewData["Message"] = "This is a message passed via ViewData.";
ViewData["UserCount"] = 150;
return View();
}
}
@{
ViewData["Title"] = "Home Page"; // This sets the ViewData["Title"] which can be used in _Layout.cshtml
}
@ViewData["PageTitle"]
@ViewData["Message"]
Current users online: @ViewData["UserCount"]
@* Using ViewData to render a link with dynamic text *@
@if (ViewData["UserCount"] > 100)
{
Read more about our active users.
}
You can also access ViewData in your _Layout.cshtml file, for example, to set the browser tab title dynamically.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MyApp</title>
<!-- Other head elements -->
</head>
<body>
<!-- Your layout content -->
@RenderBody()
<!-- Other body elements -->
</body>
</html>
Since ViewData stores values as object, you'll often need to cast them to their specific types when accessing them in the view. It's good practice to check if the key exists or if the value is not null before casting to avoid runtime errors.
@* Safely accessing and casting ViewData *@
@{
string pageTitle = ViewData["PageTitle"] as string;
int? userCount = ViewData["UserCount"] as int?;
}
@if (!string.IsNullOrEmpty(pageTitle))
{
@pageTitle
}
@if (userCount.HasValue && userCount.Value > 100)
{
We have @userCount active users.
}
else if (userCount.HasValue)
{
We have @userCount users online.
}
else
{
User count information is not available.
}
ViewData is not type-safe. This means that if you try to cast to the wrong type, you might encounter runtime errors. For scenarios requiring strong type safety, consider using ViewBags or, more commonly, strongly-typed Models passed to the view.
| Feature | ViewData | ViewBag | Strongly-Typed Models |
|---|---|---|---|
| Type | ViewDataDictionary (key-value pairs) |
Dynamic object (properties) | Custom C# class |
| Type Safety | No (requires casting) | No (requires casting if accessed via ViewData, but dynamic by nature) | Yes |
| Performance | Slightly less performant due to dictionary lookups and casting | Slightly less performant due to dynamic dispatch | Most performant |
| Ease of Use | Requires explicit casting, can be verbose | Easy to use, less verbose than ViewData | Requires defining a model class, but provides IntelliSense and compile-time checks |
| Common Use | Simple data transfer, page titles, small messages | Similar to ViewData, often used for convenience | Primary mechanism for passing complex data to views |
For passing multiple complex data items or when type safety is crucial, use strongly-typed models. For passing a few simple, dynamic pieces of data where type safety is less of a concern, ViewBag or ViewData can be acceptable. However, ViewBag is generally considered more concise than ViewData for simple scenarios.
ViewData is a foundational tool in ASP.NET Core MVC for passing data between controllers and views. While it offers flexibility, it's essential to be mindful of its non-type-safe nature and choose the appropriate data transfer mechanism based on your application's needs.