I'm creating ASP.Net Core Web API using .Net Core 2.1 and I need to create custom middleware for global exception handling. What I am trying to do is capture JSON request when exception happened in my application. And since I'm using custom middleware, I want the JSON request available in my middleware. How I can accomplish this?
I've tried creating custom middleware for centralized exception handling by following an article from Marinko Spasojevic and slightly modified it to capture the json request. It seems the request already unavailable since the exception occurred inside controllers action (not in the middleware). Here is my code:
Here is my Error Log model
public class ErrorLog
{
public DateTime LogDate { get; set; }
public string URL { get; set; }
public string Request { get; set; }
public string Source { get; set; }
public string Message { get; set; }
}
Here is standard response model used in my project
public class BaseResponse<T> : IBaseResponse where T : class
{
public bool Status { get; set; }
public string Message { get; set; }
public IEnumerable<T> Data { get; set; }
}
Here is my custom exception middleware
public class GlobalException
{
private readonly RequestDelegate _next;
private readonly ICustomLogger _logger;
public GlobalException(RequestDelegate next, ICustomLogger logger)
{
_logger = logger;
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (Exception ex)
{
ErrorLog log = new ErrorLog();
log = await HandleLogError(httpContext, ex);
_logger.LogError(log); // Custom build logger
await HandleExceptionAsync(httpContext, ex);
}
}
private static async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
BaseResponse<object> response = new BaseResponse<object>();
response.Status = false;
response.Message = "There is an exception occured.";
response.Data = new List<object>();
await context.Response.WriteAsync(response.Serialize());
}
private static async Task<ErrorLog> HandleLogError(HttpContext context, Exception exception)
{
Stream body = context.Request.Body;
context.Request.EnableRewind();
byte[] buffer = new byte[Convert.ToInt32(context.Request.ContentLength)];
await context.Request.Body.ReadAsync(buffer, 0, buffer.Length);
string requestText = Encoding.UTF8.GetString(buffer);
context.Request.Body = body;
ErrorLog log = new ErrorLog();
UriBuilder builder = new UriBuilder();
builder.Scheme = context.Request.Scheme;
builder.Host = context.Request.Host.Host;
builder.Path = context.Request.Path.ToString();
builder.Query = context.Request.QueryString.ToString();
log.LogDate = DateTime.Now;
log.URL = builder.Uri.ToString();
log.Request = requestText;
log.Source = exception.Source;
log.Message = exception.Message;
return log;
}
}
And finnally register the middleware
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseMiddleware<GlobalException>();
...
}
So, anyone can give me an enlightenment? Any help would be appreciated and thank you before.