The Intent.AspNetCore.Mvc module generates ASP.NET Core MVC Controller classes for applications that require server-side rendering with Razor views, as opposed to pure API controllers.
Overview
While the standard Controllers module generates API controllers for JSON responses, the MVC module generates traditional MVC controllers that work with Razor views to return HTML. This is ideal for server-rendered web applications.
What Gets Generated
MVC Controller
Generated MVC controllers return views instead of JSON:
public class ProductsController : Controller
{
private readonly IProductService _productService ;
public ProductsController ( IProductService productService )
{
_productService = productService ;
}
[ HttpGet ]
public async Task < IActionResult > Index ( CancellationToken cancellationToken )
{
var products = await _productService . GetAllAsync ( cancellationToken );
return View ( products );
}
[ HttpGet ]
public async Task < IActionResult > Details ( Guid id , CancellationToken cancellationToken )
{
var product = await _productService . GetByIdAsync ( id , cancellationToken );
if ( product == null )
return NotFound ();
return View ( product );
}
[ HttpGet ]
public IActionResult Create ()
{
return View ();
}
[ HttpPost ]
[ ValidateAntiForgeryToken ]
public async Task < IActionResult > Create (
CreateProductDto dto ,
CancellationToken cancellationToken )
{
if ( ! ModelState . IsValid )
return View ( dto );
await _productService . CreateAsync ( dto , cancellationToken );
return RedirectToAction ( nameof ( Index ));
}
[ HttpGet ]
public async Task < IActionResult > Edit ( Guid id , CancellationToken cancellationToken )
{
var product = await _productService . GetByIdAsync ( id , cancellationToken );
if ( product == null )
return NotFound ();
return View ( product );
}
[ HttpPost ]
[ ValidateAntiForgeryToken ]
public async Task < IActionResult > Edit (
Guid id ,
UpdateProductDto dto ,
CancellationToken cancellationToken )
{
if ( ! ModelState . IsValid )
return View ( dto );
await _productService . UpdateAsync ( id , dto , cancellationToken );
return RedirectToAction ( nameof ( Index ));
}
[ HttpPost ]
[ ValidateAntiForgeryToken ]
public async Task < IActionResult > Delete ( Guid id , CancellationToken cancellationToken )
{
await _productService . DeleteAsync ( id , cancellationToken );
return RedirectToAction ( nameof ( Index ));
}
}
View Stubs
The module generates stub view files for each controller action:
@model ProductDto
@{
ViewData["Title"] = "Product Details";
}
<h1>@ViewData["Title"]</h1>
<div>
<h4>Product</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">@Html.DisplayNameFor(model => model.Name)</dt>
<dd class="col-sm-10">@Html.DisplayFor(model => model.Name)</dd>
<dt class="col-sm-2">@Html.DisplayNameFor(model => model.Price)</dt>
<dd class="col-sm-10">@Html.DisplayFor(model => model.Price)</dd>
</dl>
</div>
<div>
<a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
<a asp-action="Index">Back to List</a>
</div>
Key Features
View-Based Returns HTML views using Razor
Form Handling Built-in support for form posts and model binding
Anti-Forgery Automatic CSRF protection
Validation ModelState validation integration
MVC vs API Controllers
Feature MVC Controllers API Controllers Primary Use Server-rendered HTML REST APIs returning JSON Base Class ControllerControllerBaseReturns IActionResult with ViewsActionResult<T> with JSONAnti-Forgery Required for POST Not required Content Negotiation Returns HTML Returns JSON/XML Module Intent.AspNetCore.MvcIntent.AspNetCore.Controllers
When to Use MVC Controllers
Choose MVC controllers when:
Your application needs to generate HTML on the server using Razor views
Building a classic web application with pages and navigation
Search engines need to crawl fully-rendered HTML content
You’re not using React, Angular, or Vue for the frontend
View Structure
The module generates views organized by controller:
Views/
├── Products/
│ ├── Index.cshtml
│ ├── Details.cshtml
│ ├── Create.cshtml
│ ├── Edit.cshtml
│ └── Delete.cshtml
├── Customers/
│ ├── Index.cshtml
│ └── ...
├── Shared/
│ ├── _Layout.cshtml
│ └── _ValidationScriptsPartial.cshtml
└── _ViewStart.cshtml
MVC controllers handle form submissions with model binding:
[ HttpPost ]
[ ValidateAntiForgeryToken ]
public async Task < IActionResult > Create (
[ FromForm ] CreateProductDto dto ,
CancellationToken cancellationToken )
{
// Validate the model
if ( ! ModelState . IsValid )
{
// Return to the form with validation errors
return View ( dto );
}
// Process the form
var productId = await _productService . CreateAsync ( dto , cancellationToken );
// Redirect to success page
return RedirectToAction ( nameof ( Details ), new { id = productId });
}
Corresponding Razor form:
@model CreateProductDto
<form asp-action="Create" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Price" class="control-label"></label>
<input asp-for="Price" class="form-control" />
<span asp-validation-for="Price" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Service Contract Dispatch
MVC controllers use service contract dispatch to interact with your application layer:
public class ProductsController : Controller
{
private readonly IProductService _service ;
private readonly IUnitOfWork _unitOfWork ;
public ProductsController (
IProductService service ,
IUnitOfWork unitOfWork )
{
_service = service ;
_unitOfWork = unitOfWork ;
}
[ HttpPost ]
[ ValidateAntiForgeryToken ]
public async Task < IActionResult > Create (
CreateProductDto dto ,
CancellationToken cancellationToken )
{
if ( ! ModelState . IsValid )
return View ( dto );
await _service . CreateAsync ( dto , cancellationToken );
await _unitOfWork . SaveChangesAsync ( cancellationToken );
return RedirectToAction ( nameof ( Index ));
}
}
Installation
Dependencies
Intent.Application.Contracts (>= 5.0.4)
Intent.Common.CSharp
Intent.Modelers.Services
Intent.OutputManager.RoslynWeaver
Hybrid Applications
You can use both MVC and API controllers in the same application. Install both modules to have some endpoints return views and others return JSON.
Example hybrid setup:
// MVC Controller for admin pages
public class AdminProductsController : Controller
{
// Returns HTML views
}
// API Controller for mobile app
[ ApiController ]
[ Route ( "api/products" )]
public class ProductsApiController : ControllerBase
{
// Returns JSON
}
Next Steps
API Controllers Generate REST API controllers instead
Razor Pages Consider Razor Pages for simpler scenarios
Blazor Explore Blazor for component-based UIs