NET Centric ComputingUnit 315 min read
Controllers, Views, Razor Syntax & MVC Workflow in ASP.NET Core
Unit 3 of NET Centric Computing explores ASP.NET Core MVC's three-tier architecture, focusing on Controllers (request handling), Views (dynamic HTML generation), and Razor Syntax (C embedded in HTML). It covers action methods, view rendering, tag helpers, and real-world scenarios like eSewa's dynamic form generation or
TAKEAWAYS:
- Controllers act as middleware between HTTP requests and business logic, returning ActionResults (View, JSON, Redirect, etc.).
- Views use Razor syntax (
@Model,@foreach,@Html.TagHelpers) to dynamically generate HTML from C# models. - Tag Helpers (e.g.,
<form asp-controller="Home" asp-action="Login">) replace HTML helpers for cleaner markup. - The MVC workflow follows: Request → Controller → Model → View → Response, with Razor parsing server-side before sending HTML.
- Partial Views and View Components enable reusable UI components (e.g., headers, footers).
- Layouts (e.g.,
_Layout.cshtml) standardize page structure across views.
1. Controllers: The Traffic Directors of ASP.NET Core MVC
Controllers are C# classes that handle HTTP requests, process data, and return responses. They sit between the client (browser/app) and the model (data/logic).
How Controllers Work
- Route Binding: ASP.NET Core maps incoming URLs to controller actions using attributes (
[Route],[HttpGet],[HttpPost]). - Action Methods: Each method handles a specific HTTP verb (GET, POST, PUT, DELETE).
- Return Types: Actions return
ActionResultobjects (e.g.,View(),Json(),Redirect()).
Example: A Simple HomeController
[Route("Home")]
public class HomeController : Controller
{
// GET: /Home/Index
[HttpGet]
public IActionResult Index()
{
var message = "Welcome to ASP.NET Core MVC!";
return View(message); // Renders Index.cshtml with the model
}
// POST: /Home/Login
[HttpPost]
public IActionResult Login(string username, string password)
{
if (ValidateUser(username, password))
return Redirect("/Dashboard");
return View("LoginError"); // Renders a different view
}
}
Key Attributes
| Attribute | Purpose |
|---|---|
[Route("Home")] |
Base route for the controller (e.g., /Home/Index). |
[HttpGet] |
Restricts action to GET requests. |
[HttpPost] |
Restricts action to POST requests (e.g., form submissions). |
[FromBody] |
Binds request body to method parameters (used in APIs). |
[FromQuery] |
Binds query string parameters (e.g., /Home/Search?q=ASP.NET). |
2. Views: Dynamic HTML Generation with Razor
Views are .cshtml files that combine HTML with Razor syntax to generate dynamic content. They receive data from controllers via ViewBag, ViewData, or @Model.
Razor Syntax Basics
| Syntax | Example | Output |
|---|---|---|
| Inline Code | @DateTime.Now |
12:34 PM, June 5, 2024 |
| Model Access | @Model.Name |
"John Doe" (from model) |
| Loops | @foreach(var item in Model.Items) |
Renders each item in a list. |
| Conditional | @if(Model.IsAdmin) { ... } |
Shows content only for admins. |
| HTML Helpers | @Html.ActionLink("Home", "Index") |
<a href="/Home/Index">Home</a> |
Example: Index.cshtml (View)
@model string <!-- Declares the model type -->
<h1>@Model</h1> <!-- Displays the string passed from controller -->
@if (User.IsInRole("Admin"))
{
<p>Admin Panel: <a href="/Admin">Go</a></p>
}
Partial Views
Reusable UI components (e.g., headers, footers) stored in /Views/Shared/.
Example: _Header.cshtml
<header>
<h1>@ViewData["SiteName"]</h1>
<nav>
@Html.ActionLink("Home", "Index", "Home")
</nav>
</header>
Usage in a View:
@await Html.PartialAsync("_Header", new { SiteName = "MyApp" })
3. Tag Helpers: Simplifying HTML with C#
Tag Helpers replace HTML helpers (e.g., @Html.TextBox()) with cleaner, HTML-like syntax. They run at compile time.
classDiagram
class FormTagHelper {
+asp-controller: string
+asp-action: string
+method: string
}
class InputTagHelper {
+asp-for: string
+class: string
}
class LabelTagHelper {
+asp-for: string
}
FormTagHelper --> InputTagHelper : contains
FormTagHelper --> LabelTagHelper : contains
note for FormTagHelper "Generates <form> with action=/Home/Login"
note for InputTagHelper "Generates <input name='User.Name'>"Tag Helper class relationships in ASP.NET CoreCommon Tag Helpers
| Tag Helper | Example | Output |
|---|---|---|
<form> |
<form asp-controller="Home" asp-action="Login"> |
<form action="/Home/Login" method="post"> |
<input> |
<input asp-for="User.Name" /> |
<input name="User.Name" type="text"> |
<label> |
<label asp-for="User.Email"> |
<label for="User.Email">Email</label> |
<select> |
<select asp-items="Model.Categories"> |
<select><option>Cat1</option></select> |
<a> (ActionLink) |
<a asp-action="Details" asp-route-id="@item.Id"> |
<a href="/Home/Details/123">Details</a> |
Example: Login Form with Tag Helpers
<form asp-controller="Account" asp-action="Login" method="post">
<div class="form-group">
<label asp-for="UserName"></label>
<input asp-for="UserName" class="form-control" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
4. The MVC Workflow: Request to Response
sequenceDiagram
participant Client
participant Router
participant Controller
participant Model
participant View
participant Response
Client->>Router: GET /Home/Index
Router->>Controller: Invoke HomeController.Index()
Controller->>Model: Fetch data (e.g., DB query)
Model-->>Controller: Return Product[] products
Controller->>View: Render Index.cshtml with products
View-->>Controller: Return ViewResult
Controller-->>Response: Send HTML to Client
Response->>Client: Display pageReal-World Example: Daraz Product Listing
- Request: User visits
/Products/Electronics. - Controller:
ProductsController.GetElectronics()fetches data from a database. - View:
Electronics.cshtmluses@foreachto loop through products and@Html.DisplayFor()to show prices. - Response: Dynamic HTML page with product cards is sent to the browser.
5. Layouts and Partial Views: Reusability
Layouts (_Layout.cshtml)
- Define shared structure (headers, footers, navigation).
- Views inherit from layouts using
@{ Layout = "~/Views/Shared/_Layout.cshtml"; }.
Example Layout:
<!DOCTYPE html>
<html>
<head>
<title>@ViewData["Title"] - MyApp</title>
</head>
<body>
@RenderBody() <!-- Renders the main content of the view -->
@RenderSection("Scripts", required: false) <!-- Optional scripts -->
</body>
</html>
View Sections
Allow views to override parts of the layout.
Example: Index.cshtml
@{
Layout = "_Layout";
ViewData["Title"] = "Home Page";
}
<h1>Welcome</h1>
@section Scripts {
<script src="~/js/home.js"></script>
}
6. Common Action Result Types
| Result Type | Example | Use Case |
|---|---|---|
View() |
return View(); |
Renders a view with default model. |
View(model) |
return View(products); |
Renders a view with a model. |
PartialView() |
return PartialView("_Header"); |
Returns a partial view fragment. |
Json() |
return Json(new { Success = true }); |
Returns JSON for APIs. |
Redirect() |
return Redirect("/Home"); |
Redirects to another URL. |
RedirectToAction() |
return RedirectToAction("Details", "Product"); |
Redirects to another action. |
Example: API Controller (JSON Responses)
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
[HttpGet("{id}")]
public IActionResult Get(int id)
{
var product = _db.Products.Find(id);
if (product == null) return NotFound();
return Ok(product); // Returns JSON with HTTP 200
}
[HttpPost]
public IActionResult Create([FromBody] Product product)
{
_db.Products.Add(product);
_db.SaveChanges();
return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
}
}
In the Real World
eSewa (Nepal)
- Idea Used: Controllers + Razor Views
- How: When you submit a bill payment form, eSewa’s backend uses a
PaymentControllerto process the request. TheConfirmPayment.cshtmlview dynamically generates a confirmation page with Razor, showing your transaction details (e.g.,@Model.Amount,@Model.ReceiptNumber).
Daraz (Nepal)
- Idea Used: Tag Helpers + Partial Views
- How: Product listing pages use
<div asp-items="Model.Products">to loop through items. The "Add to Cart" button is a partial view (_AddToCart.cshtml) reused across all product pages.
Khalti (Nepal)
- Idea Used: Action Results (JSON + Redirect)
- How: After you initiate a payment, Khalti’s API returns
Json(new { Status = "Pending", Url = "/payment/confirm" }). If successful, it redirects to/payment/successusingRedirectToAction().
Ncell’s MyNcell App (Nepal)
- Idea Used: Layouts + View Sections
- How: The app’s dashboard uses
_Layout.cshtmlfor the navigation bar and footer. Individual pages (e.g.,BillPayment.cshtml) inject their content into@RenderBody()while keeping the same header/footer.
Google Search (Global)
- Idea Used: Controllers + Dynamic Views
- How: When you search for "ASP.NET Core," Google’s backend routes the request to a
SearchController, which fetches results and renders them inSearchResults.cshtmlusing Razor loops (@foreach(var result in Model.Results)).
Worked Example: Kathmandu Traffic Route Optimization
Scenario: Imagine a traffic management system for Kathmandu where sensors send data to a backend. The system uses ASP.NET Core MVC to display real-time traffic maps.
Controller:
[Route("Traffic")] public class TrafficController : Controller { [HttpGet("Map")] public IActionResult Map() { var trafficData = _sensorService.GetLiveData(); return View(trafficData); // Renders Map.cshtml } }View (
Map.cshtml):@model List<TrafficSensorData> <div id="map" style="height: 500px;"></div> @foreach (var sensor in Model) { <script> // JavaScript to plot sensor data on a map plotTrafficPoint(@sensor.Latitude, @sensor.Longitude, @sensor.Status); </script> }Tag Helper for Filters:
<select asp-for="Filter" asp-items="Model.AvailableFilters"> <option value="">All</option> </select>
Real-World Tie-In:
- The system could integrate with NTC’s traffic cameras (like those on ntc.gov.np) to fetch live data.
- Partial Views could show alerts for congested routes (e.g.,
_CongestionAlert.cshtml).
Exam Tip
Controller Questions:
- Always show attributes (
[Route],[HttpGet]) and return types (IActionResult). - For API controllers, use
[Route("api/[controller]")]and returnJson(). - Common Pitfalls:
- Forgetting
[HttpPost]for form submissions (causes 405 errors). - Not specifying
[FromBody]for JSON payloads in POST/PUT.
- Forgetting
- Always show attributes (
Razor Syntax:
- Memorize
@model,@foreach,@if, and@Html.TagHelpers. - Exam Favorite: Write a view that loops through a list and uses
@Html.DisplayFor(). - Trick:
@ViewDatavs.@ViewBag:@ViewDatais strongly typed (requires casting).@ViewBagis dynamic (no casting needed).
- Memorize
Action Results:
- JSON: Use
Json()for APIs. - Redirects: Use
RedirectToAction()for internal links. - Partial Views: Use
PartialView()for reusable components.
- JSON: Use
Layouts and Partial Views:
- Always declare
@{ Layout = "_Layout"; }in views. - Use
@RenderSection()for optional scripts/styles.
- Always declare
Real-World Scenarios:
- eSewa/Khalti: Focus on controllers handling payments and Razor views for receipts.
- Daraz: Emphasize tag helpers for product listings and partial views for carts.
- Ncell: Highlight layouts for consistent UI and JSON responses for APIs.
Final Pro Tip:
- Draw the MVC workflow in exams if asked about "how ASP.NET Core processes a request."
- Use Mermaid diagrams in answers to show controller actions or Razor loops (examiners love visuals!).
- Practice: Build a mini-project (e.g., a "Library Management" app) with:
- A
BooksControllerwith CRUD actions. - Razor views for listing/editing books.
- A layout with a navigation bar.
- A
In the real world
- Daraz (Nepal): Uses Controllers to handle
/Products/Electronicsrequests, fetching data from its database via Models, then rendering dynamic product cards in Views with Razor loops (@foreach). - eSewa: Employs Tag Helpers in its payment forms (e.g.,
<input asp-for="UserPhone" />) to bind user input to C# model properties, ensuring validation and security. - Ncell App: Leverages Partial Views for reusable UI components like headers/footers across all pages, reducing code duplication and improving maintainability.
Based on the TU BSc CSIT syllabus for NET Centric Computing (CSC367), unit 3.
Discussion
Loading…