N M
asked on
C# HTTPrequest - how to get the whole request and whole response.
I have the below small console program to consume a restAPI.
I have difficulty to see *what exactly* am I sending (the WHOLE request) and *what exactly* am I getting back as a response (the WHOLE response).
I have tried many Console.WriteLines with various arguments, but seems I have not managed to have a concrete results (WHOLE request and WHOLE response).
Could you help me please? The whole code below.
I have difficulty to see *what exactly* am I sending (the WHOLE request) and *what exactly* am I getting back as a response (the WHOLE response).
I have tried many Console.WriteLines with various arguments, but seems I have not managed to have a concrete results (WHOLE request and WHOLE response).
Could you help me please? The whole code below.
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace TEST_API
{
public partial class ConsentHeaders
{
[JsonProperty("CL-ID")]
public string CL_ID { get; set; }
[JsonProperty("X-ID")]
public string X_ID { get; set; }
[JsonProperty("P-Token")]
public string P_Token { get; set; }
}
public partial class access
{
[JsonProperty("aP2")]
public string aP2 { get; set; } = "allAccounts";
[JsonProperty("aAcc")]
public string aAcc { get; set; } = "allAccounts";
}
public partial class ConsentBody
{
[JsonProperty("access")]
public access access { get; internal set; }
[JsonProperty("combinedServiceIndicator")]
public Boolean combinedServiceIndicator { get; set; } = false;
[JsonProperty("frequencyPerDay")]
public int frequencyPerDay { get; set; } = 4;
[JsonProperty("recurringIndicator")]
public Boolean recurringIndicator { get; set; } = false;
[JsonProperty("validUntil")]
public string validUntil { get; set; } = "2019-12-31";
}
class Program
{
private static void Main()
{
ConsentHeaders cust_consent_headers = new ConsentHeaders
{
X_ID = "d587612Xq99",
CL_ID = "8010aFQ9127",
P_Token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ",
};
ConsentBody cust_consent = new ConsentBody //{ };
// You may choose to edit/update any value, otherwise defaults will be used.
{
access = new access
{
aP2 = "allAccounts",
aAcc = "allAccounts"
},
combinedServiceIndicator = false,
frequencyPerDay = 4,
recurringIndicator = false,
validUntil = "2019-12-31"
};
System.Uri URL = new System.Uri("http://MyService:8001/some/api/do/something");
CreateConsentAsync(URL, cust_consent_headers, cust_consent).GetAwaiter().GetResult();
}
static HttpClient client = new HttpClient();
static async Task CreateConsentAsync(Uri HTTPaddress, ConsentHeaders cconsentHeaders, ConsentBody cconsent)
{
try
{
client.BaseAddress = HTTPaddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
client.DefaultRequestHeaders.Add("CL-ID", cconsentHeaders.CL_ID);
client.DefaultRequestHeaders.Add("X-ID", cconsentHeaders.X_ID);
client.DefaultRequestHeaders.Add("P-Token", cconsentHeaders.P_Token);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, client.BaseAddress);
request.Content = new StringContent(JsonConvert.SerializeObject(cconsent, Formatting.Indented), System.Text.Encoding.UTF8, "application/json");
await client.SendAsync(request).ContinueWith(responseTask => { Console.WriteLine("Response: {0}", responseTask.Result);});
}
catch (Exception e)
{
Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message);
}
Console.ReadLine();
}
}
}
You can use tracing to capture the raw request and response. I built a library to make it a very simple process:
https://github.com/jhilgeman/HttpRawTraceListener
https://github.com/jhilgeman/HttpRawTraceListener
On a side note, an even easier way is to install and use Fiddler. That program simply examines HTTP network activity on your computer (across all apps, not just your program). My library I mentioned above is if you need to access the request/response from within code.
ASKER
Thank you, I will try it, but seems complicated, I was just looking to have all the request in a string and all the response in a string. I will make an efrort to follow your advice - thank you!
I was just looking to have all the request in a string and all the response in a string.That's ultimately what my library does.
The bigger question is what your goal is. If it's just to examine and debug, then Fiddler is the simplest approach. You can be up and running in minutes.
If you need it as a string because you want to do something extra with the data, then that is what my library is for. Make sure you look at the example. It's very simple to set up.
ASKER
Thank you, I just copied the code inside the same namespace, added System.IO and now thinking how to use it to get the whole request and response.. Thank you
I'm not sure what you mean by copying the code into your namespace. It's intended to be a drop-in file (you cannot remove the copyright or header).
Just save the file as-is into your project and then in your solution explorer, right-click the file and Include it to make it part of your project. Then just use the example usage code. The example shows you how to get the full request and response.
Just save the file as-is into your project and then in your solution explorer, right-click the file and Include it to make it part of your project. Then just use the example usage code. The example shows you how to get the full request and response.
ASKER
I will do so (no I didnt remove the copyright, no need to pretend is my code). Just trying to see how to get the full string response.. I will follow your advice here.
ASKER
Still trying to have the request, I was wondering if there is any simpler solution; kindly advise.
I have added this namespace, in different file, and all is good.
I am inside my code, in the static async Task CreateConsentAsync and inside the 'try' right after my 'await client.SendAsync' I put the trace listener.
Here is that part:
So, I have error on the "System.Diagnostics.HttpRa wTraceList ener_Finis hedCommuni cation" that says it does not recognise the namespace ("does not exist in System.Diagnostics namespace, are you missing an assembly or reference?" - but I am not). And in private void HttpRawTraceListener_Finis hedCommuni cation does not accept the "private" (throws error "the modifier 'private' is not valid for this item".
Apologies, couldn't debug so I revert code to previous stage.
I have added this namespace, in different file, and all is good.
I am inside my code, in the static async Task CreateConsentAsync and inside the 'try' right after my 'await client.SendAsync' I put the trace listener.
Here is that part:
try
{
client.BaseAddress = HTTPaddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
client.DefaultRequestHeaders.Add("... etc.
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, client.BaseAddress);
request.Content = new StringContent(JsonConvert.SerializeObject(cconsent, Formatting.Indented), System.Text.Encoding.UTF8, "application/json");
Console.WriteLine(client.DefaultRequestHeaders);
Console.WriteLine(JsonConvert.SerializeObject(cconsent, Formatting.Indented));
await client.SendAsync(request).ContinueWith(responseTask => { Console.WriteLine("Response: {0}", responseTask.Result); });
System.Diagnostics.HttpRawTraceListener.Initialize();
System.Diagnostics.HttpRawTraceListener.FinishedCommunication += System.Diagnostics.HttpRawTraceListener_FinishedCommunication;
private void HttpRawTraceListener_FinishedCommunication(object sender, System.Diagnostics.CommunicationEventArgs e)
{
Console.WriteLine("Raw Request: " + e.Communication.RequestString);
Console.WriteLine("Raw Response: " + e.Communication.ResponseString);
}
}
catch (Exception e)
{
Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message);
}
Console.ReadLine();
}
So, I have error on the "System.Diagnostics.HttpRa
Apologies, couldn't debug so I revert code to previous stage.
You are not putting the code in the right place. These two lines:
The second part is an event handler method so it needs to go outside your current method.
To be honest, I'm concerned that you don't know C# syntax. This is not something you should try to do by cutting and pasting code snippets from the internet. It is more involved than that because of the way that .NET handles tracing. So at minimum you should understand event handlers and static vs. non-static code. Otherwise this won't make sense (and there is no simpler way to get the full request and response in every situation - both successful and failed requests).
System.Diagnostics.HttpRawTraceListener.Initialize();
System.Diagnostics.HttpRawTraceListener.FinishedCommunication += System.Diagnostics.HttpRawTraceListener_FinishedCommunication;
...need to only run once, so put them into your startup code.The second part is an event handler method so it needs to go outside your current method.
To be honest, I'm concerned that you don't know C# syntax. This is not something you should try to do by cutting and pasting code snippets from the internet. It is more involved than that because of the way that .NET handles tracing. So at minimum you should understand event handlers and static vs. non-static code. Otherwise this won't make sense (and there is no simpler way to get the full request and response in every situation - both successful and failed requests).
ASKER
Dear sir,
Indeed I am trying to have a steep learn curve to walk, but I am trying. After all, this is the reason I am asking the help from the experts here.. both solving a problem and learning through this.
I am taking your advice quite seriously, however, still the code didn't compile.. Well, I will keep trying..
You may look my effort and error messages in the comment before yours.
Thank you for the comments, and I appreciate your time.
Indeed I am trying to have a steep learn curve to walk, but I am trying. After all, this is the reason I am asking the help from the experts here.. both solving a problem and learning through this.
I am taking your advice quite seriously, however, still the code didn't compile.. Well, I will keep trying..
You may look my effort and error messages in the comment before yours.
Thank you for the comments, and I appreciate your time.
ASKER
So, for the POST indeed this would reveal the Post request:
Console.WriteLine("POST Request: " + "\r\n" + client.DefaultRequestHeade rs + "\r\n" + JsonConvert.SerializeObjec t(cconsent , Formatting.Indented) + "\r\n");
and for the response, instead of using the
responseTask.Result.Conten t.ReadAsSt ringAsync( ).Result
Console.WriteLine("POST Request: " + "\r\n" + client.DefaultRequestHeade
and for the response, instead of using the
responseTask.Resultwe can use
responseTask.Result.Conten
static async Task CreateConsentAsync(Uri HTTPaddress, ConsentHeaders cconsentHeaders, ConsentBody cconsent)
{
HttpClient client = new HttpClient();
try
{
client.BaseAddress = HTTPaddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
//add more headears here as per your needs..
client.DefaultRequestHeaders.Add("my header", yourValue);
//...
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, client.BaseAddress);
request.Content = new StringContent(JsonConvert.SerializeObject(cconsent, Formatting.Indented), System.Text.Encoding.UTF8, "application/json");
Console.WriteLine("POST Request: " + "\r\n" + client.DefaultRequestHeaders + "\r\n" + JsonConvert.SerializeObject(cconsent, Formatting.Indented) + "\r\n");
await client.SendAsync(request).ContinueWith(responseTask => {Console.WriteLine("Response:\r\n{0}", responseTask.Result.Content.ReadAsStringAsync().Result);});
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message);
Console.ReadLine();
}
}
ASKER
Any better (as simple as possible) solutions, to get the whole POST message and the whole Request sent back, are welcome. Thank you.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you very much!
ASKER