I'd like to have every request logged automatically. In previous .Net Framwork WebAPI project, I used to register a delegateHandler to do so.
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.MessageHandlers.Add(new AutoLogDelegateHandler());
}
AutoLogDelegateHandler.cs
public class AutoLogDelegateHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var requestBody = request.Content.ReadAsStringAsync().Result;
return await base.SendAsync(request, cancellationToken)
.ContinueWith(task =>
{
HttpResponseMessage response = task.Result;
//Log use log4net
_LogHandle(request, requestBody, response);
return response;
});
}
}
an example of the log content:
------------------------------------------------------
2017-08-02 19:34:58,840
uri: /emp/register
body: {
"timeStamp": 1481013427,
"id": "0322654451",
"type": "t3",
"remark": "system auto reg"
}
response: {"msg":"c556f652fc52f94af081a130dc627433","success":"true"}
------------------------------------------------------
But in .NET Core WebAPI project, there is no WebApiConfig
, or the register function at Global.asax GlobalConfiguration.Configure(WebApiConfig.Register);
So is there any way to achieve that in .NET Core WebAPI?
ActionFilter
will work until you need to log only requests processed by MVC middleware (as controller actions).
If you need logging for all incoming requests, then you need to use a middleware approach.
Good visual explanation:
Note that middleware order is important, and if your logging should be done at the start of pipeline execution, your middleware should be one of the first one.
Simple example from docs:
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
// Do loging
// Do work that doesn't write to the Response.
await next.Invoke();
// Do logging or other work that doesn't write to the Response.
});
You can create your own filter attribute...
public class InterceptionAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var x = "This is my custom line of code I need executed before any of the controller actions, for example log stuff";
base.OnActionExecuting(actionContext);
}
}
... and you would register it with GlobalFilters, but since you said you're using .NET Core, this is how you can try proceeding...
From learn.microsoft.com:
You can register a filter globally (for all controllers and actions) by adding it to the MvcOptions.Filters collection in the ConfigureServices method in the Startup class:
Let us know if it worked.
P.S. Here's a whole tutorial on intercepting requests with WebAPI, in case someone needs more details.
For someone that wants a quick and (very) dirty solution for debugging purposes (that works on .Net Core 3), here's an expansion of this answer that's all you need...
app.Use(async (context, next) =>
{
var initialBody = context.Request.Body;
using (var bodyReader = new StreamReader(context.Request.Body))
{
string body = await bodyReader.ReadToEndAsync();
Console.WriteLine(body);
context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));
await next.Invoke();
context.Request.Body = initialBody;
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With