ASP.NET Core equivalent of ASP.NET MVC 5's HttpException
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
ASP.NET MVC 5 had HttpException for returning HTTP error status codes from controllers. ASP.NET Core removed this class entirely. Instead, you return status code results directly from controllers (return NotFound(), return BadRequest()), throw custom exceptions handled by middleware, or use the built-in ProblemDetails response format. The shift reflects ASP.NET Core's middleware-based architecture where HTTP responses are not driven by exceptions but by explicit result objects.
The Old Way: ASP.NET MVC 5
HttpException would be caught by the framework and converted into the corresponding HTTP status code response. This class does not exist in ASP.NET Core.
Fix 1: Return Status Code Results Directly (Recommended)
ASP.NET Core controllers have built-in helper methods for every common HTTP status:
Available helper methods:
| Method | Status Code | Use Case |
Ok() | 200 | Successful response |
Created() | 201 | Resource created |
NoContent() | 204 | Successful with no body |
BadRequest() | 400 | Invalid input |
Unauthorized() | 401 | Not authenticated |
Forbid() | 403 | Not authorized |
NotFound() | 404 | Resource missing |
Conflict() | 409 | State conflict |
StatusCode(n) | Any | Custom status code |
Fix 2: Custom Exception with Middleware
Create your own HttpException replacement and handle it globally with middleware:
Now you can throw exceptions like the old MVC 5 pattern:
Fix 3: UseExceptionHandler with ProblemDetails
ASP.NET Core 7+ has built-in ProblemDetails support:
This automatically converts unhandled exceptions and error status codes into RFC 7807 ProblemDetails JSON:
Fix 4: Exception Filters
For controller-scoped exception handling:
Comparison of Approaches
| Approach | Scope | Best For |
Return NotFound() etc. | Per action | API controllers, simple cases |
| Custom middleware | Global | Consistent error format across all endpoints |
| ProblemDetails | Global | Standards-compliant REST APIs |
| Exception filters | Controller/global | MVC apps needing controller-level handling |
Common Pitfalls
- Throwing exceptions for control flow: Returning
NotFound()is cheaper than throwing an exception. Exceptions have stack trace overhead. Reserve exceptions for truly exceptional situations, not expected cases like "record not found." - Missing
[ApiController]attribute: Without it, ASP.NET Core does not automatically return 400 for invalid ModelState. Add[ApiController]to all API controllers. - Swallowing exception details in production: Never expose stack traces or internal details in production responses. Use
ProblemDetailswith environment-aware detail levels. - Forgetting
UseExceptionHandlerorder: Middleware order matters.UseExceptionHandler()must be registered early in the pipeline (beforeUseRouting()) to catch exceptions from downstream middleware. - Using
HttpContext.Response.StatusCodeafter response started: Once headers are sent, you cannot change the status code. Exception middleware must checkcontext.Response.HasStartedbefore writing.
Summary
- ASP.NET Core removed
HttpException— use controller helper methods (NotFound(),BadRequest()) instead - For throw-and-catch patterns, create a custom exception class with global exception middleware
- Use
ProblemDetails(ASP.NET Core 7+) for RFC 7807 compliant error responses - Exception filters provide controller-scoped handling for MVC applications
- Prefer returning status code results over throwing exceptions for expected error conditions

