Solved

Asp.NET Web api logging request and response

Posted on 2016-07-29
10
79 Views
Last Modified: 2016-08-11
Hi All

I want to log both JSON request and response made to my web api. Can you show me the standard way of implementing this

Thanks
Adib
0
Comment
Question by:Member_2_7967608
  • 6
  • 4
10 Comments
 
LVL 23

Expert Comment

by:Ioannis Paraskevopoulos
ID: 41735670
Hi,

I have created such a solution which logs the messages in a table in the db. Of course you may use whatever logging solution you like.

I am using Ninject for Dependency Injection. In my case DbContext is my DB repository.
For this you need to create a class that will derive from DelegatingHandler. You will need to override SendAsync.

public class LoggingHandler: DelegatingHandler
{
    public DbContext _context {get;set;}
    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        //Get the _context
        _context = (DbContext)request.GetDependencyScope().GetService(typeof(DbContext));

        //Declare the new Entity
        var logEntity = new Log();
        
        //Read the request body
        var requestMessageBytes = await request.Content.ReadAsByteArrayAsync();

        //Decode the message bytes to string and log them
        logEntity.RequestMessage = Encoding.UTF8.GetString(requestMessageBytes);

        //Log the request Headers
        var requestHeaders = request.Headers.Where(x => x.Value != null && x.Value.Count() > 0);

        var requestHeadersString = String.Empty;
        foreach(var header in request.Headers)
        {
            requestHeadersString += String.Format("{0}: {1}{2}", header.Key, String.Join(", ", header.Value), Environment.NewLine);
        }
        logEntity.RequestHeaders = requestHeadersString;

        //Release the request to the condroller and read the response
        var response = await base.SendAsync(request, cancellationToken);

        //Log the response status
        logEntity.ResponseHTTPStatusCode = response.StatusCode

        //Log the response body
        byte[] responseMessageBytes;

        if(response.Content != null)
        {
            responseMessage = await response.Content.ReadAsByteArrayAsync();
        }

        logEntity.ResponseBody = Encoding.UTF8.GetString(responseMessage);


       //Log the Response Headers
        var responseHeaders = response.Headers

        var responseHeadersString = String.Empty
        foreach(var header in response.Headers)
        {
            responseHeadersString += String.Format("{0}: {1}{2}", header.Key, String.Join(", ", header.Value), Environment.NewLine);
        }

        logEntity.ResponseHeaders = requestHeadersString;


       //Save the entry
        _context.Entities.Log.Add(logEntity);
        _context.SaveChanges();

    }

}

Open in new window


Now you need to register this so it takes effect. What i do for this is put the following in Global.asax Application_Start :

        GlobalConfiguration.Configuration.MessageHandlers.Add(New LoggingHandler())

Open in new window


Please make note that in my case i was using VB.Net, so i had to transform the code to C# for you. This means that i have not really tested this exact implementation but i guess it will. Let me know how it goes.

Giannis
0
 

Author Comment

by:Member_2_7967608
ID: 41737953
Thanks . This would capture incoming Requests and outgoing Response from Web api?
0
 
LVL 23

Accepted Solution

by:
Ioannis Paraskevopoulos earned 500 total points
ID: 41737998
Yes,

If you see line 29 of the code above SendAsync will send the request to the requested Controller Action and get the response.

This whole method will log the following:

Request Body,
Request Headers,
Response Body,
Response Headers,
Response HTTP Status code

Giannis
0
 

Author Comment

by:Member_2_7967608
ID: 41741630
{"RequestMessage":"{\r\n  \"BID\" : \"1\",\r\n  \"EID\": \"2\",\r\n  \"TD\": \"3\",\r\n  \"SID\": \"4\",\r\n  \"ID\": \"5\",\r\n  \"Key\": \"93b\"\r\n}","RequestHeaders...................................

I am able to log. But I am getting  \r\n   or \  in the    logged request and response. Can we get rid of it.
0
 

Author Comment

by:Member_2_7967608
ID: 41752079
Can we disable the web api handler or set it in Web.config. I don't want to trace in production.
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 23

Expert Comment

by:Ioannis Paraskevopoulos
ID: 41752099
Hi,

If you want to set it in the web.config then you could do it like this:

In web.config:

 <appSettings>
...
    <add key="EnableLogging" value="true" />
...
 </appSettings>

Open in new window


In Global.asax Application_Start :

if(ConfigurationManager.AppSettings["EnableLogging"] == "true")
{
    GlobalConfiguration.Configuration.MessageHandlers.Add(New LoggingHandler())
}

Open in new window


Another way without the web.config change would be:


In Global.asax Application_Start :

#if DEBUG
    GlobalConfiguration.Configuration.MessageHandlers.Add(New LoggingHandler())
#endif

Open in new window


I prefer the first way though ;-).

By the way, i missed your other question on how to get rid of the \r\n s etc. Do you still have a problem with that?

Giannis
0
 

Author Comment

by:Member_2_7967608
ID: 41752151
Thanks..Yes I still have that issue.
0
 
LVL 23

Expert Comment

by:Ioannis Paraskevopoulos
ID: 41752172
Well you may try this:

var escapedString = "{\r\n  \"SomeResponse\":\r\n  {\r\n    \"FIrstAttribute\":8,\r\n    \"SecondAttribute\":\"On\"\r\n  }\r\n}";
var result = System.Text.RegularExpressions.Regex.Unescape(escapedString);

Open in new window


Giannis
0
 

Author Comment

by:Member_2_7967608
ID: 41752935
Thanks
0
 

Author Closing Comment

by:Member_2_7967608
ID: 41752937
Thanks
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now