Hi @Aakash Bashyal ,
From your description, you want to capture the 404 error (caused by the incorrect URL or the resource is not found,) and format the response with the generic response model, right?
For the 404 errors caused by incorrect routing or request URLs, you could use the UseStatusCodePages middleware.
Code as below:
app.UseStatusCodePages(new StatusCodePagesOptions()
{
HandleAsync = async (ctx) =>
{
if (ctx.HttpContext.Response.StatusCode == 404)
{
await ctx.HttpContext.Response.WriteAsJsonAsync(new RouteNotFoundException("Route not found"));
}
}
});
For the 404 errors caused by the resource is not found, in the action method, you could use try-catch
statement to capture the exception, then throw a RouteNotFoundException, then use exception handler to handle the exception, code as below:
Action method:
// GET api/<ValuesController>/5
[HttpGet("{id}")]
public string Get(int id)
{
throw new RouteNotFoundException("File not found exception thrown in API Action method");
return "value";
}
Startup.Configure method:
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var exceptionHandlerPathFeature =
context.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is RouteNotFoundException)
{
await context.Response.WriteAsJsonAsync(new RouteNotFoundException(exceptionHandlerPathFeature.Error.Message));
}
else
{
context.Response.Redirect("/Home/Error");
}
});
});
The result as below:
Besides, you could also create a middleware to handle the exception:
Create a ErrorHandlerMiddleware middleware with the following code:
public class ErrorHandlerMiddleware
{
private readonly RequestDelegate _next;
public ErrorHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception error)
{
var response = context.Response;
response.ContentType = "application/json";
switch (error)
{
case RouteNotFoundException e:
// custom application error
response.StatusCode = (int)HttpStatusCode.BadRequest;
break;
case KeyNotFoundException e:
// not found error
response.StatusCode = (int)HttpStatusCode.NotFound;
break;
default:
// unhandled error
response.StatusCode = (int)HttpStatusCode.InternalServerError;
break;
}
var result = JsonSerializer.Serialize(new RouteNotFoundException(error?.Message));
await response.WriteAsync(result);
}
}
}
Register the middleware in the Startup.Configure method:
app.UseMiddleware<ErrorHandlerMiddleware>();
The result as below:
The Startup.Configure method as below:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
//app.UseExceptionHandler("/Home/Error");
////use UseExceptionHandler method to handle the exception
//app.UseExceptionHandler(errorApp =>
//{
// errorApp.Run(async context =>
// {
// var exceptionHandlerPathFeature =
// context.Features.Get<IExceptionHandlerPathFeature>();
// if (exceptionHandlerPathFeature?.Error is RouteNotFoundException)
// {
// await context.Response.WriteAsJsonAsync(new RouteNotFoundException(exceptionHandlerPathFeature.Error.Message));
// }
// else
// {
// context.Response.Redirect("/Home/Error");
// }
// });
//});
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseStatusCodePages(new StatusCodePagesOptions()
{
HandleAsync = async (ctx) =>
{
if (ctx.HttpContext.Response.StatusCode == 404)
{
await ctx.HttpContext.Response.WriteAsJsonAsync(new RouteNotFoundException("Route not found"));
}
}
});
app.UseRouting();
app.UseAuthorization();
app.UseSession();
app.UseMiddleware<ErrorHandlerMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Reference: Exception handler lambda
If the answer is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best Regards,
Dillion