I created a simple REST API with ASP.NET Web API. For testing purpose I would like to add some tracing. So I added NLog to my project. At this moment my logging is like this:
// POST api/values
public void Post([FromBody]string value)
{
logger.Trace("Request: {0} api/values", Request.Method);
_repository.insert(value);
logger.Trace("Response: {0} api/values", Request.Method);
}
In every method I added a logger.Trace at the top then bottom of my methods. I have 2 issue with this method:
Point 1 is not a real issue for now (see bellow) but I quickly need something to check every JSON body my API receive.
I already tried this
// POST api/values
public void Post([FromBody]string value)
{
logger.Trace("Request: {0} api/values {1}", Request.Method, Request.Body);
_repository.insert(value);
logger.Trace("Response: {0} api/values", Request.Method);
}
But there is no Body property on Request.
I also found an interesting documentation for my point 1:http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi
That's what you have action filters for...to do something before/after an action method is a executing/executed
public class MyCustomFilter : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
//Do something here before an action method starts executing
}
public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext context)
{
//Do something here after an action method finished executing
}
}
Then, you'll need to plug this filter in the asp.net pipeline...when the application starts, whether you use owin/katana or global.asax it doesn't matter...
GlobalConfiguration.Configuration.Filters.Add(new MyCustomFilter());
The line above will add that filter to all action methods. If you want to turn tracing off for some action methods, simply add a flag/switch property to the action filter so that you can switch tracing off for some actions...
public class MyCustomFilter : System.Web.Http.Filters.ActionFilterAttribute
{
public bool DisableTracing{get;set;}
public override void OnActionExecuting(HttpActionContext actionContext)
{
if(!DisableTracing){
//Do something here before an action method starts executing
}
}
public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext context)
{
if(!DisableTracing){
//Do something here before an action method starts executing
}
}
}
And now you can turn it of on controller action...
[MyCustomFilter(DisableTracing = true)]
public IHttpActionResult MyAction(int id){}
To read the JSON object from the request's body simply read the content of the request as below...
request.Content.ReadAsStringAsync().Result;
The solution of Leo seems correct for MVC but for Http REST API I had to implement the solution from http://www.c-sharpcorner.com/UploadFile/1492b1/restful-day-sharp6-request-logging-and-exception-handingloggin/
public class HttpLoggingFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext filterContext)
{
//Do something here
}
public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
{
//Do something here
}
}
After testing both method on my code I can tell the code from Leo is performed on an page refresh bit not on simple REST request.
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