C# asp.net MVC is a web application framework that provides a model-view-controller architecture. The MVC pattern separates the application into three main components: the model, the view, and the controller. This separation of concerns makes it easier to manage and maintain the application. This structure also makes it easier to test and debug the application.

  • Model: The model represents the data and core business logic related to data of the application. It is responsible for managing the data and the rules for accessing and updating the data. The model is independent of the user interface and can be reused across different views.
  • View: The view is responsible for presenting the data to the user, think of HTML Templates. It is the UI of the application and is responsible for rendering the data to the user. The view is independent of the model and the controller and can be reused across different models and controllers.
  • Controller: The controller is primarily responsible for handling user input and requests. It processes the input, interacts with the model, and selects the view to be rendered. The controller is responsible for the flow of the application and is the glue between the model and the view.

Underneath, it uses kestrel server to host the application and uses asp.net core for web development.

This structure allows us to follow a common pattern or standard which is useful for large teams and enterprise applications. It also makes it easier to maintain and extend the application over time.

Getting Started

Create a new project using the dotnet command-line interface.

dotnet new mvc -n MyMvcApp

This will create a new MVC project with this structure:

.
├── Controllers
│   └── HomeController.cs
├── Models
│   └── ErrorViewModel.cs
├── MyMvcApp.csproj
├── Program.cs
├── Properties
│   └── launchSettings.json
├── Views
│   ├── Home
│   │   ├── Index.cshtml
│   │   └── Privacy.cshtml
│   ├── Shared
│   │   ├── Error.cshtml
│   │   ├── _Layout.cshtml
│   │   ├── _Layout.cshtml.css
│   │   └── _ValidationScriptsPartial.cshtml
│   ├── _ViewImports.cshtml
│   └── _ViewStart.cshtml
├── appsettings.Development.json
├── appsettings.json
└── wwwroot

This structure has a sample application with HomeController.

you can run this project using the following command:

dotnet run

wwwroot contains the static files like css, js, images etc. which will be available to the client. wwwroot will be served under the root url.

eg: wwwroot/css/site.css will be available at http://localhost:5000/css/site.css

Routing

Routing is configured at Program.cs file:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

This will implicitly map the routes to the controllers and actions.

eg:

// HomeController.cs

public class HomeController : Controller
{
    public IActionResult Index()
    {
        // This will render Views/Home/Index.cshtml
        return View();
    }
}
  • http://localhost:5000/ will map to HomeController and Index action.

Other controllers can be added and will be automatically discovered.

// AboutController.cs

// will be available at /about
public class AboutController : Controller
{
    // will be available at /about/action
    public IActionResult Action()
    {
        // This will render Views/About/Action.cshtml
        return View();
    }
}

Controllers

Controllers are used to handle requests and return responses. These are responsible for processing the input, interacting with the model, and selecting the view to be rendered.

// HomeController.cs

public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

Possible Action Returns

  • View(): This will render the view with the same name as the action.
  • View(string viewName): This will render the specified view.
  • View(model): This will render the view with the specified model.
  • PartialView(string partialViewName): This will render a partial view.
  • PartialView(model): This will render a partial view with the specified model.
  • RedirectToAction(): This will redirect to another action.
  • Redirect(): This will redirect to another URL.
  • Json(): This will return a JSON response.
  • File(): This will return a file as a response.
  • Content(): This will return a string as a response.
  • StatusCode(): This will return a status code response.
    • Ok(): This will return a 200 response.
    • Created(): This will return a 201 response.
    • BadRequest(): This will return a 400 response.
    • Unauthorized(): This will return a 401 response.

Handling POST requests:

// HomeController.cs

[HttpPost]
public IActionResult Index(FormData data)
{
    // This will handle the POST request
    if(!ModelState.IsValid)
    {
        // Process the data
        return View(data);
    }

    return Created();
}

Handling Query parameters:

// HomeController.cs
public IActionResult Index(string id)
{
    // id will be available as query parameter
    return View();
}

Views

View templates (.cshtml) are used to render the UI. These can be used in controller and will have a default discovery format of Views/[ControllerName]/[ActionName].cshtml.

the View() method in controller will look for a view with the same name as the action.

eg:

// HomeController.cs

public class HomeController : Controller
{
    public IActionResult Index()
    {
        // This will render Views/Home/Index.cshtml
        return View();
    }
}

This will look for Index.cshtml in Views/Home folder.

.
├── Views
│   ├── Home
│   │   ├── Index.cshtml

Standard HTML Helpers

  • Html.BeginForm(): Generates a form tag. This helper can specify the action, controller, form method (GET or POST), and HTML attributes.
  • Html.TextBoxFor(): Generates a text input element for a specified model property.
  • Html.TextAreaFor(): Creates a textarea element for a specified model property.
  • Html.PasswordFor(): Creates a password input element for a specified model property.
  • Html.CheckBoxFor(): Generates a checkbox input element for a specified model property.
  • Html.RadioButtonFor(): Creates a radio button input element for a specified model property.
  • Html.DropDownListFor(): Generates a dropdown list for a specified model property.
  • Html.ListBoxFor(): Creates a list box for a specified model property.
  • Html.LabelFor(): Generates a label element for a specified model property.
  • Html.DisplayFor(): Renders the display template for the specified model property.
  • Html.EditorFor(): Renders the editor template for the specified model property.
  • Html.ValidationMessageFor(): Displays a validation message for a specified model property.
  • Html.HiddenFor(): Generates a hidden input element for a specified model property.

Link Helpers

  • Html.ActionLink(): Creates an anchor tag that links to an action method in a controller.
  • Html.RouteLink(): Generates an anchor tag that links to a route defined in the route collection.

Ajax Helpers

Shared Views

Shared views are views that can be used in many places. These are usually used for common components like header, footer, etc. Shared folder will be available by default in all views.

eg:

// Shared/_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <title>@ViewData["Title"] - My Mvc App</title>
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav>
            <ul>
                <li><a href="/">Home</a></li>
                <li><a href="/about">About</a></li>
            </ul>
        </nav>
    </header>
    <main>
        @RenderBody()
    </main>
    <footer>
        &copy; 2024 - My Mvc App
    </footer>
</body>
</html>

This layout can be used across different views by specifying it in the view.

// Index.cshtml

@{
    ViewData["Title"] = "Home";
    Layout = "_Layout"; // This will use Views/Shared/_Layout.cshtml
}

<h1>Welcome to My Mvc App</h1>

Partial Views

We can also create partial cshtml files which can be used in other views. This can be in Shared folder or in any other folder.

eg:

// Views/Home/_Sidebar.cshtml

<aside>
    <h3>Navigation</h3>
    <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about">About</a></li>
    </ul>
</aside>

This partial view can be used within other views using the Partial method.

// Index.cshtml

@{
    ViewData["Title"] = "Home";
    Layout = "_Layout";
}

<h1>Welcome to My Mvc App</h1>

@Html.Partial("Home/_Sidebar") // This will render Views/Home/_Sidebar.cshtml

or in controllers

// HomeController.cs

public class HomeController : Controller
{
    public IActionResult SideBar()
    {
        // This will render Views/Shared/_Sidebar.cshtml
        return PartialView("Home/_Sidebar");
    }
}

View Model

We can bind a model to the view using the @model directive. This will allow us to pass data to the view.

// Views/Home/Index.cshtml
@model MyMvcApp.Models.HomeViewModel

@{
    ViewData["Title"] = "Home";
    Layout = "_Layout";
}

<h1>Welcome to My Mvc App</h1>
<p>@Model.Message</p>
// HomeController.cs

public IActionResult Index()
{
    var model = new HomeViewModel
    {
        Message = "Welcome to My Mvc App"
    };
    return View(model);
}

We can also use this in partial views and layouts.

// Views/Shared/_Partial.cshtml

@model MyMvcApp.Models.HomeViewModel

<p>@Model.Message</p>
// Views/Home/Index.cshtml

@{
    ViewData["Title"] = "Home";
    Layout = "_Layout";
}

<h1>Welcome to My Mvc App</h1>
@Html.Partial("Shared/_Partial", new HomeViewModel { Message = "Welcome to My Mvc App" })

Viewbag and ViewData

ViewBag and ViewData are used to pass data to the view. These are untyped and can be used to pass data to the view.

// HomeController.cs

public IActionResult Index()
{
    ViewBag.Message = "Welcome to My Mvc App";
    ViewData["Message"] = "Welcome to My Mvc App";
    return View();
}
// Views/Home/Index.cshtml

@{
    ViewData["Title"] = "Home";
    Layout = "_Layout";
}

<h1>Welcome to My Mvc App</h1>
<p>@ViewBag.Message</p>
<p>@ViewData["Message"]</p>