
Description
Migrates ASP.NET MVC global filters (GlobalFilterCollection, HandleErrorAttribute, FilterConfig) to ASP.NET Core exception handling middleware and filter pipeline. Use when upgrading MVC apps that register filters via GlobalFilters.Filters.Add(), have a FilterConfig.cs, use HandleErrorAttribute, or need to convert custom IActionFilter/IExceptionFilter implementations to ASP.NET Core equivalents. Also triggers for global error handling migration, MVC-to-Core filter conversion, and UseExceptionHandler setup.
SKILL.md
ASP.NET MVC Global Filters Migration
Overview
Migrate GlobalFilterCollection-based filters from ASP.NET MVC to ASP.NET Core middleware and filter pipeline. ASP.NET Core replaces HandleErrorAttribute with UseExceptionHandler middleware because middleware runs earlier in the pipeline and catches errors from all middleware, not just controller actions.
Workflow
Track progress across these steps:
Migration Progress:
- [ ] Step 1: Identify main controller from routing
- [ ] Step 2: Add exception handler middleware
- [ ] Step 3: Add error action methods
- [ ] Step 4: Create error views
- [ ] Step 5: Convert custom filters
- [ ] Step 6: Remove FilterConfig and GlobalFilters references
Step 1: Identify Main Controller
Determine the main controller name from routing configuration. Check Program.cs for route registration first, then fall back to RouteConfig.cs if the project hasn't been fully migrated. The default route typically maps to HomeController. This controller will host the error-handling action methods.
Step 2: Add Exception Handler Middleware
If HandleErrorAttribute was registered as a global filter, add exception handling middleware in Program.cs:
app.UseExceptionHandler("/<MainControllerName>/Error");
app.UseStatusCodePagesWithReExecute("/<MainControllerName>/StatusErrorCode", "?code={0}");
Replace <MainControllerName> with the controller name from Step 1. Skip if these lines already exist.
UseExceptionHandler replaces HandleErrorAttribute globally, while UseStatusCodePagesWithReExecute provides user-friendly pages for HTTP status codes like 404 and 403.
Step 3: Add Error Action Methods
Open the main controller file and add an Error action method if missing:
public IActionResult Error()
{
return View();
}
Add a StatusErrorCode action method to the same controller:
public IActionResult StatusErrorCode(int code)
{
return View("StatusErrorCode", code);
}
If other methods in the controller use attribute routing, add [Route] attributes to these methods as well to stay consistent.
Step 4: Create Error Views
Create Views/Shared/Error.cshtml if it does not exist:
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Oops! Something went wrong.</h1>
<p class="text-muted">An unexpected error occurred. Please try again later.</p>
Create Views/Shared/StatusErrorCode.cshtml if it does not exist:
@{
ViewData["Title"] = "Status Error Code";
var code = Context.Request.Query["code"];
}
<h1 class="text-danger">Oops! Something went wrong.</h1>
@if (code == "404")
{
<p class="text-muted">The page you are looking for could not be found.</p>
}
else if (code == "403")
{
<p class="text-muted">You do not have permission to access this resource.</p>
}
else if (code == "500")
{
<p class="text-muted">An internal server error occurred. Please try again later.</p>
}
else
{
<p class="text-muted">An unexpected error occurred (Status code: @code).</p>
}
Place views under Views/Shared/ for app-wide access, or under Views/<ControllerName>/ if only that controller handles errors.
Step 5: Convert Custom Filters
Convert any custom filters registered in GlobalFilterCollection to ASP.NET Core filter interfaces (IActionFilter, IAsyncActionFilter, IExceptionFilter, etc.). Register them in Program.cs:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add<MyCustomFilter>();
});
ASP.NET Core filters use dependency injection natively, so constructor-injected services work without extra setup.
Step 6: Remove FilterConfig
Remove FilterConfig.cs (or equivalent class that called GlobalFilters.Filters.Add()). Search for and remove all references to GlobalFilters.Filters across the codebase. If the class contained only filter registration code, delete the entire file; otherwise, remove only the filter-related code.
Success Criteria
UseExceptionHandlerandUseStatusCodePagesWithReExecuteconfigured inProgram.cs- Error and StatusErrorCode action methods exist in the main controller
- Error views created under
Views/Shared/or appropriate controller folder - Custom filters converted to ASP.NET Core interfaces and registered
- No
FilterConfig.csorGlobalFilters.Filtersreferences remain - Project builds without errors
More skills from the upgrade-agent-plugins repository
View all 19 skillsconverting-to-cpm
migrate .NET projects to Central Package Management
Jul 18.NETMicrosoftMigrationcreating-winforms-custom-controls
create custom WinForms controls
Jul 3.NETWindowsWinUImanaging-winforms-high-dpi-layout
design high-DPI responsive WinForms layouts
Jul 18DesignDesktopUI ComponentsWindowsmanaging-winforms-mvvm
implement MVVM pattern in WinForms
Jul 18.NETWindowsWinUImigrating-aspnet-framework-to-core
migrate ASP.NET Framework to Core
Jul 3.NETASP.NET CoreBackendMigrationmigrating-documentdb-to-cosmos
migrate DocumentDB to Cosmos DB
Jul 3AzureCosmos DBDatabaseMigration
More from Microsoft
View publisherplaywright-trace
inspect Playwright trace files
playwright
Apr 6DebuggingPlaywrightTestingrushstack-best-practices
manage Rush monorepos with best practices
rushstack
Apr 6EngineeringLocal DevelopmentMicrosoftProject Management +1azure-ai-agents-persistent-dotnet
build AI agents with Azure .NET SDK
skills
Jul 3.NETAgentsAzureLLMazure-ai-anomalydetector-java
build anomaly detection applications with Java
skills
May 13AnalyticsAzureData AnalysisJava +2azure-ai-contentsafety-java
build content moderation applications with Azure AI
skills
Jul 7AI InfrastructureAzureJavaSecurityazure-ai-contentsafety-py
detect harmful content with Azure AI Content Safety
skills
Jul 18AzureComplianceLLMMicrosoft +2