Last Updated: May 15, 2025
ASP.NET MVC is a web application framework developed by Microsoft that implements the Model-View-Controller (MVC) design pattern. It provides an alternative to the traditional ASP.NET Web Forms, offering a more structured approach to web application development by separating concerns, which enhances testability and maintainability.
ASP.NET MVC is built around three fundamental components: Model, View, and Controller. Each plays a distinct role in application architecture, contributing to a clean separation of concerns.
The Model represents the application's data and business logic. It contains the classes that define data structures and manage interactions with the database. Model objects are responsible for retrieving, storing, and processing application data.
The View is responsible for rendering the User Interface (UI) to the client. Views are typically created using data from the Model and are defined using Razor syntax in .cshtml files. They provide a dynamic and responsive presentation layer.
The Controller handles incoming user requests. It acts as a coordinator between the Model and the View. Controllers process user input, perform business logic using Models, and return a View result to render the response. Essentially, they manage the application flow.
In ASP.NET MVC, the lifecycle refers to the sequence of steps involved in processing a web request from initiation to completion. It is categorized into two primary phases:
The Application Life Cycle begins when the web application starts on the server and ends when it is shut down. This cycle is managed by the ASP.NET runtime within the IIS environment.
Global.asax
. This lifecycle handles each individual HTTP request received by the application. It defines how the request is processed and how the response is generated.
RouteData
. ControllerFactory
to instantiate the controller. Authorize
) are applied. ActionResult
such as ViewResult
or JsonResult
. A high-level view of the MVC application lifecycle, where you can understand the major stages that every MVC application passes through in the request processing pipeline.
Routing in ASP.NET MVC is a powerful mechanism that maps incoming browser requests to controller actions. It defines how URLs are interpreted and how they determine which code should be executed.
When a user sends a request to an MVC application, the routing engine analyzes the URL and matches it to a pattern defined in the route configuration. This determines which controller and action method should handle the request.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
ASP.NET MVC also supports attribute routing, where routes are specified using attributes directly on controllers and actions for better clarity and control.
[Route("products/{id}")]
public ActionResult Details(int id)
{
// Action logic here
}
This allows precise definition of URL structures and is especially useful in RESTful APIs.
Attribute Routing allows you to define routes directly on controller actions using attributes. This approach was introduced in ASP.NET MVC 5 and offers better readability and control, especially useful for RESTful services and complex routing scenarios.
With attribute routing, routes are defined by decorating controller actions with the [Route]
attribute instead of defining them centrally in RouteConfig.cs
.
In RouteConfig.cs
, add the following line:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Enable attribute routing
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
public class ProductsController : Controller
{
[Route("products/details/{id}")]
public ActionResult Details(int id)
{
// Logic here
return View();
}
}
This route maps URLs like /products/details/5
to the Details
action with id = 5
.
[RoutePrefix("store")]
public class StoreController : Controller
{
[Route("product/{id:int}")]
public ActionResult Product(int id)
{
return View();
}
}
This maps URLs like /store/product/10
to the Product
action only if id
is an integer.
Attribute Routing is ideal when you want more control over your route definitions directly in your controllers. It is especially useful for RESTful API design, custom URL structures, and scenarios where routes are tightly coupled to action methods.
{controller}/{action}/{id}
pattern.
[RoutePrefix("api/products")]
public class ProductsController : Controller
{
[Route("")]
public ActionResult GetAll()
{
// Get all products
}
[Route("{id:int}")]
public ActionResult GetById(int id)
{
// Get product by ID
}
}
In this example, URLs like /api/products
and /api/products/5
map directly to specific methods, making your routing explicit and maintainable.
RouteConfig.cs
. In ASP.NET MVC, Filters are attributes used to inject pre-processing and post-processing logic into the request life cycle. They help in separating cross-cutting concerns such as logging, authorization, error handling, and caching.
[Authorize]
, [AllowAnonymous]
OnActionExecuting
, OnActionExecuted
OnResultExecuting
, OnResultExecuted
[HandleError]
, OnException
public class LogActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Custom logic before action method
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Custom logic after action method
}
}
You can apply filters globally, at the controller level, or on individual action methods:
[LogActionFilter]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
Action Filters in ASP.NET MVC are a type of filter that allows you to run custom logic before and after the execution of an action method. These filters help in implementing cross-cutting concerns like logging, auditing, or input validation.
public class LogActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Pre-action logic here
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Post-action logic here
}
}
[LogActionFilter]
public ActionResult Index()
{
return View();
}
Action filters are ideal when you want to apply logic around action execution without cluttering your controller code.
A Partial View in ASP.NET MVC is a reusable view component that renders a portion of HTML content. It is used to break down large views into smaller, manageable, and reusable parts, which promotes clean and modular design.
Step 1: Create a Partial View (e.g., _UserProfile.cshtml
)
@model MyApp.Models.User
<div class="user-profile">
<p>Name: @Model.Name</p>
<p>Email: @Model.Email</p>
</div>
Step 2: Render it inside another view:
@Html.Partial("_UserProfile", Model.User)
Using partial views promotes code reuse and simplifies complex UIs by isolating responsibilities.
Aspect | View | Partial View |
---|---|---|
Purpose | Renders a complete web page with layout, sections, and full HTML content. | Renders a fragment or portion of HTML to be included inside other views. |
Layout | Uses the shared layout (_Layout.cshtml) or specific layout files. | Does not use a layout by default; it’s just a snippet of HTML. |
Use Case | Used for full page rendering of content. | Used for reusable components like headers, footers, or AJAX-updatable parts. |
Rendering | Returned from controller action using return View() . | Rendered inside a view using @Html.Partial() or @Html.RenderPartial() . |
Example | User dashboard page showing full content with menus and layout. | User profile snippet rendered inside the dashboard page. |
Aspect | ViewData | ViewBag |
---|---|---|
Type | Dictionary of objects (ViewDataDictionary) accessed by string keys. | Dynamic property wrapper around ViewData using C# dynamic features. |
Syntax | ViewData["Name"] = "John"; | ViewBag.Name = "John"; |
Null Safety | Compile-time checking is less strict; needs casting when retrieving data. | More convenient syntax with dynamic typing but no compile-time type checking. |
Lifetime | Valid only during the current HTTP request. | Valid only during the current HTTP request. |
Usage | Useful when you want to pass data using string keys explicitly. | More developer-friendly syntax, especially in Razor views. |
Performance | Slightly faster as it is a dictionary. | Slightly slower due to dynamic feature overhead. |
Both ViewBag and ViewData are used to pass data from Controller to View for a single request, but ViewBag offers a more readable and cleaner syntax.
TempData is a key-value dictionary used in ASP.NET MVC to store data temporarily between two consecutive requests. It is particularly useful when redirecting from one controller action to another and you need to persist some data during that redirection.
It is derived from the TempDataDictionary
class and is part of the ControllerBase
class. TempData uses the underlying Session state to store the data, which means it persists data on the server for a short period.
TempData keeps the information for the duration of an HTTP Request. Once the value is read, it is marked for deletion at the end of that request. If you need to keep it longer, you can use TempData.Keep()
or TempData.Peek()
.
Feature | TempData | Session |
---|---|---|
Lifetime | One subsequent request (unless kept) | Until explicitly removed or expired |
Use Case | Temporary message passing between actions | Storing user data like cart, user login info |
Read Behavior | Removed after reading once | Persists until cleared |
Storage Mechanism | Internally uses Session | Stored on the server (InProc, StateServer, SQLServer) |
// Controller A
public ActionResult Submit()
{
TempData["SuccessMessage"] = "Data saved successfully!";
return RedirectToAction("Confirm");
}
// Controller B
public ActionResult Confirm()
{
// Will be available only once unless Peek or Keep is used
ViewBag.Message = TempData["SuccessMessage"];
return View();
}
TempData["key"]
– Reads and removes the data.TempData.Peek("key")
– Reads data without removing it. TempData.Keep("key")
– Keeps the data for the next request. In ASP.NET MVC, Authentication and Authorization are fundamental security concepts used to control access to parts of a web application. They help verify who a user is and determine what they can do.
Authentication is the process of verifying the identity of a user. It answers the question: "Who are you?"
Once authenticated, a user’s identity is established using credentials such as a username and password. The most common authentication methods in ASP.NET MVC include:
🔧 Example: Configuring Forms Authentication in web.config
:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="30" />
</authentication>
Authorization determines whether an authenticated user has permission to access a specific resource or action. It answers the question: "What are you allowed to do?"
ASP.NET MVC uses the [Authorize]
attribute to restrict access:
[Authorize]
public ActionResult Dashboard()
{
return View();
}
You can also restrict by roles:
[Authorize(Roles = "Admin")]
public ActionResult AdminPanel()
{
return View();
}
To allow anonymous access explicitly:
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
Aspect | Authentication | Authorization |
---|---|---|
Purpose | Identify the user | Grant or deny access |
Order | Comes first | Comes after successful authentication |
Implementation | Forms, Windows, OAuth | [Authorize] attribute, Role-based checks |
Dependency Injection (DI) is a software design pattern that allows classes to receive their dependencies from external sources rather than creating them directly.
You can use popular DI containers such as Ninject, Autofac, or Unity to implement DI in MVC.
Example using constructor injection:
// Interface
public interface IProductService
{
List<Product> GetAll();
}
// Implementation
public class ProductService : IProductService
{
public List<Product> GetAll() { /* logic */ }
}
// Controller
public class ProductController : Controller
{
private readonly IProductService _service;
public ProductController(IProductService service)
{
_service = service;
}
public ActionResult Index()
{
var products = _service.GetAll();
return View(products);
}
}
In ASP.NET Core, DI is built-in. Register services in Program.cs
or Startup.cs
:
builder.Services.AddScoped<IProductService, ProductService>();
_ViewStart
in ASP.NET MVC? The _ViewStart.cshtml
file is a special Razor view file that runs before every view is rendered in an ASP.NET MVC application. It is primarily used to define common settings or code that should apply to multiple views, such as specifying a layout page.
Instead of repeating the layout declaration in every view, you can put the following in _ViewStart.cshtml
:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
This means every view will use the specified layout by default, improving code reuse and maintainability.
Key points about _ViewStart
:
_ViewStart.cshtml
files scoped to different folders. Scaffolding is a code generation framework in ASP.NET MVC that automatically generates the boilerplate code for CRUD (Create, Read, Update, Delete) operations based on your data model. It helps speed up development by creating controllers, views, and sometimes data context classes with minimal manual coding.
When you scaffold a controller or view for a model, the tool generates:
Scaffolding can be done using Visual Studio UI or the command line (CLI) tools, and it is especially useful for rapid prototyping and initial development.
Benefits of Scaffolding:
In ASP.NET MVC, Action Methods are public methods in a Controller class that respond to HTTP requests. When a user makes a request to a URL, the MVC framework uses the routing system to determine which controller and which action method to invoke.
Controller
. ActionResult
or one of its derived types such as ViewResult
, JsonResult
, RedirectResult
, etc. public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Details(int id)
{
var model = db.Products.Find(id);
return View(model);
}
}
Action methods can return different types of results:
ViewResult
– returns a view pageRedirectResult
– redirects to another URLJsonResult
– returns JSON dataFileResult
– returns a file to downloadContentResult
– returns plain text contentEmptyResult
– returns no resultprivate
or static
. [NonAction]
attribute are not treated as actions. [NonAction]
public void HelperMethod()
{
// This will not be treated as an action method
}
You can overload action methods, but MVC cannot resolve overloaded methods based on parameters alone. You may need to use attributes like [HttpGet]
and [HttpPost]
to differentiate them.
[HttpGet]
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(Product model)
{
// Save logic
return RedirectToAction("Index");
}
In ASP.NET MVC, action methods can return various types of results derived from the ActionResult
class. Choosing the correct return type controls what the browser receives and how your application behaves.
return View("Index");
return PartialView("_ProductList");
return Json(new { success = true });
return Redirect("/Home/About");
return RedirectToAction("Index", "Home");
return Content("Hello World!");
return File(filePath, "application/pdf");
return new HttpStatusCodeResult(404);
return new EmptyResult();
Why it matters: The return type controls user experience and client-server communication. For example, JsonResult
is essential for AJAX or SPA applications, while ViewResult
suits traditional page loads.
Both RenderBody()
and RenderPage()
are Razor methods used to insert HTML content in views or layouts, but they serve different purposes.
RenderBody()
RenderBody()
is allowed per layout.<!DOCTYPE html>
<html>
<head>
<title>My App</title>
</head>
<body>
<header>
<!-- Header HTML -->
</header>
@RenderBody() <!-- Child views' content inserted here -->
<footer>
<!-- Footer HTML -->
</footer>
</body>
</html>
RenderPage()
@RenderPage("Header.cshtml")
<p>Main content here</p>
@RenderPage("Footer.cshtml")
Feature | RenderBody() | RenderPage() |
---|---|---|
Purpose | Placeholder for child views' main content | Includes any Razor page or snippet |
Usage Location | Layout pages only | Views or layouts |
Number Allowed | One per layout | Multiple per page |
Content Inserted | Child view content | Partial reusable content |
Layouts in ASP.NET MVC are Razor files that define a common template or structure shared across multiple views, similar to master pages in Web Forms. They help maintain consistent UI and avoid repeating markup like headers, footers, and navigation menus.
~/Views/Shared/_Layout.cshtml
. @RenderBody()
method to define where child views’ content will be placed. Layout
property, often in _ViewStart.cshtml
. <!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title - My MVC App</title>
<link href="~/Content/site.css" rel="stylesheet" />
</head>
<body>
<nav>
<!-- Navigation menu -->
</nav>
<section>
@RenderBody() <!-- Child view content goes here -->
</section>
<footer>
<p>© 2025 My Company</p>
</footer>
</body>
</html>
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@RenderSection()
for scripts or styles.