Search code examples
.netsslodatatrace

How can I trace oData request from a .Net DataServiceContext over SSL?


I am developing a .Net client to retrieve data from an oData service. My client uses a System.Data.Services.Client.DataServiceContext.

I would like to see the actual oData requests sent out to the server. The server uses an SSL connection and requests to the server cannot easily be sniffed. I tried to do this with Burp. I added a SendingRequest EventHandler and set the Request.Proxy property. But this gives an exception:

The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

Wireshark just shows the encrypted data.

Alternatively, I could contact the oData provider for server logs, but that would take some time. I am looking for a instantaneous trace.


Here is a sample client, that uses the Microsoft Northwind oData service.

  1. Create a Class Library;
  2. Add a Service Reference to Northwind;
  3. Create a class oDataClient;
  4. Add a method Customers();
  5. Create a Test project;
  6. Create in it a unit test for Customers();
  7. Run the test.

Method:

public class oDataClient
{
    public void Customers()
    {
        {
            var context = new Northwind.NorthwindEntities(new System.Uri("http://services.odata.org/V3/Northwind/Northwind.svc/"));

            var customers = from c in context.Customers 
                            where c.CompanyName.StartsWith("A")
                            select c;

            int count = customers.Count();
        }
    }
}

Test:

[TestMethod()]
public void CustomersTest()
{
    oDataClient target = new oDataClient();
    target.Customers();
}

Solution

  • You can use the SendingRequest2, ReceivingResponse event to trace the out going OData request in client side. see the below example for more detail.

    using Microsoft.OData.Client;
    using Simple.OData.Client;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ODataClientApp
    {
        class Program
        {
            private static string fileName = "TraceLog.log";
            private static Default.Container container;
            static void Main(string[] args)
            {
                try
                {
                    var uri = "http://localhost:32097/odata";
                    container = new Default.Container(new Uri(uri));
    
                    container.SendingRequest2 += Container_SendingRequest2;
                    container.ReceivingResponse += Container_ReceivingResponse;
                    var moviles = container.Movies.Execute().ToList();
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.ReadLine();
                }
            }
    
            private static void Container_SendingRequest2(object sender, Microsoft.OData.Client.SendingRequest2EventArgs e)
            {
                var request = e.RequestMessage as HttpWebRequestMessage;
                var x = container;
                var url = request.Url.AbsoluteUri;
                var method = request.Method;
                var authenticationLevel = request.HttpWebRequest.AuthenticationLevel;
                var impersonationLevel = request.HttpWebRequest.ImpersonationLevel.ToString();
                var headers = request.Headers;
                var sb = new StringBuilder();
                sb.AppendLine(DateTime.Now.ToString() + "------------------------------SendingRequest2 Begin---------------------------");
                sb.AppendLine("Url:" + url);
                sb.AppendLine("Method:" + method);
                sb.AppendLine("Authentication Level:" + authenticationLevel);
                sb.AppendLine("Impersonation Level:" + impersonationLevel);
                sb.AppendLine();
                sb.AppendLine("Header Info:-");
                foreach (var header in headers)
                {
                    sb.AppendFormat("{0}:{1}", header.Key, header.Value);
                    sb.AppendLine();
                }
                sb.AppendLine(DateTime.Now.ToString() + "------------------------------SendingRequest2 End-----------------------------");
                File.AppendAllText(fileName, sb.ToString());
            }
            private static void Container_ReceivingResponse(object sender, Microsoft.OData.Client.ReceivingResponseEventArgs e)
            {
                var response = e.ResponseMessage as HttpWebResponseMessage;
                var statusCode = response.StatusCode.ToString();
                var headers = response.Headers;
    
                var sb = new StringBuilder();
                sb.AppendLine(DateTime.Now.ToString() + "------------------------------ReceivingResponse Begin-------------------------");
                sb.AppendLine("Status Code:" + statusCode);
                sb.AppendLine();
                sb.AppendLine("Header Info:-");
                foreach (var header in headers)
                {
                    sb.AppendFormat("{0}:{1}", header.Key, header.Value);
                    sb.AppendLine();
                }
                sb.AppendLine(DateTime.Now.ToString() + "------------------------------ReceivingResponse End---------------------------");
                File.AppendAllText(fileName, sb.ToString());
            }
        }
    }