MVC vs MVT: ASP.NET Core MVC controllers and Razor views compared with Django

.NET Architecture & Design Patterns November 13, 2026 csharp

It is the same idea (separation of concerns) under different names.

csharp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// ======================================================================
// Q: What's the difference between MVC and MVT?
//
// It is the same idea (separation of concerns) under different names. Django's
// "View" does the job of the Controller in ASP.NET, and Django's "Template" is
// the ASP.NET View. In MVT the "controller" role (routing) is played by the
// framework itself.
// - Model: in ASP.NET Core MVC, domain entities and ViewModels / DTOs; in
//   Django, Django ORM models.
// - Receives the request: Controller (action method) in MVC; View (function or
//   class) in Django.
// - Renders HTML: View (Razor .cshtml) in MVC; Template (Django template
//   language) in Django.
// - Routing: routing middleware and attribute routes in MVC; URLconf (urls.py),
//   i.e. the framework, in Django.
// - .NET also has Razor Pages (Page Controller pattern: one PageModel per page,
//   good for form-based UI) and Web API controllers / Minimal APIs, where there
//   is no View: JSON is returned.
// - Thin controllers: the controller only handles HTTP (binding, validation,
//   status codes). Business logic goes in the application / domain layer.
// ======================================================================

// ASP.NET Core MVC: the Controller picks the Model and the View
public class ProductsController(IProductService products) : Controller
{
    public async Task<IActionResult> Details(int id, CancellationToken ct)
    {
        var vm = await products.GetDetailsAsync(id, ct);   // Model / ViewModel
        return vm is null ? NotFound() : View(vm);         // Views/Products/Details.cshtml
    }
}

@* Details.cshtml: the View *@
@model ProductDetailsVm
<h1>@Model.Name</h1>
<p>@Model.Price.ToString("C")</p>   @* Razor HTML-encodes automatically (XSS) *@

# Django (MVT): the "view" is the controller
def product_detail(request, id):
    product = get_object_or_404(Product, pk=id)
    return render(request, "products/detail.html", {"product": product})