This series is a collection of knowledge about ASP .NET Core. It just is my notes.
Part 1: Startup file.
Part 2: DI.
Part 3: Middleware.
Part 4: Host and Servers.
Part 5: Configurations.
Part 6: Environment.
Part 7: Logs.
Part 9: Routing.
Part 10: Make an HTTP Request.
Part 11: Static files.
Part 12: Authentication and Authorization.
Part 13: CORS.
There are some ways to handle exceptions while we working with Asp .net core
1. Use try-catch block
a. Best practice when using "throw"
- Throw ex: loose stack trace on downstream layer
- For example, an exception has occurred in the Data layer, Business layer catch this exception and use 'Throw Ex', at API layer will lose stack trace
- Shouldn't use like this
- Throw: keep stack trace on downstream layer
- For example, an exception has occurred in the Data layer, Business layer catch this exception and use 'Throw', at API layer will get a stack trace in detail
- Should use like this
- Throw new Exception: it will make downstream layer losing stack trace in detail
- Only use at a lower level, the downstream level should use "Throw", we will keep stack trace on the downstream level
3. Validation DDD
There are 4 possible ways to implement validation.
IsValid method: transition an entity to a state (potentially invalid) and ask it to validate itself.
Validation in application services.
TryExecute pattern.
Execute / CanExecute pattern.
There are two major types of validation.
The Execute / TryExecute pattern works best for task-based scenarios. For CRUD scenarios, you need to choose between Execute / TryExecute and validation in application services. The choice comes down to purity versus ease of implementation.
4. Centralize exception handling with IExceptionFilter
- Implement an ExceptionFilter class
- Add to the configuration method
- Throw an exception when needed.
5. [From ASP.NET Core 8] - Use IExceptionHandler
The built-in exception handler middleware uses IExceptionHandler implementations to handle exceptions.
This interface has only one TryHandleAsync method.
- If Exception can handle => return true;
- If Not => return false
- Can implement a custom logic in the method
Basic usage:
Implement of IExceptionHandler
public class GlobalExceptionHandler : IExceptionHandler
{
private readonly ILogger<GlobalExceptionHandler> logger;
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger)
{
this.logger = logger;
}
public async ValueTask<bool> TryHandleAsync(
HttpContext httpContext,
Exception exception,
CancellationToken cancellationToken)
{
this.logger.LogError(exception, "Exception occurred: {Message}", exception.Message);
var problemDetails = new ProblemDetails
{
Status = StatusCodes.Status500InternalServerError,
Title = "Server error -- apply IExceptionHandler for Global"
};
httpContext.Response.StatusCode = problemDetails.Status.Value;
await httpContext.Response
.WriteAsJsonAsync(problemDetails, cancellationToken);
return true;
}
}
Use the handler in Program file
// User Exception Handler
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
Exception Handler in new way (sample)
References:
[Microsoft Learn] - Handle errors in ASP.NET Core