C# - How to I get the HTTP Status Code from a http request - c#

I have the below code, working as expected (given correct URL etc) as a POST request. Seems I have a problem reading the Status Code (I receive a successful 201, and based on that number I need to continue processing). Any idea how to get the status code?
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");
client.DefaultRequestHeaders.Add("otherHeader", myValue);
//etc. more headers added, as needed...
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("\r\n" + "POST Request:\r\n" + client.DefaultRequestHeaders + "\r\nBody:\r\n" + JsonConvert.SerializeObject(cconsent, Formatting.Indented) + "\r\n");
await client.SendAsync(request).ContinueWith
(
responseTask =>
{
Console.WriteLine("Response: {0}", responseTask.Result + "\r\nBody:\r\n" + responseTask.Result.Content.ReadAsStringAsync().Result);
}
);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message);
Console.ReadLine();
}
}

There is a Status code in your Result.
responseTask.Result.StatusCode
Or even better
var response = await client.SendAsync(request);
var statusCode = response.StatusCode;

It helps to avoid using ContinueWith if you're already inside an async function because you can use the (much cleaner) await keyword.
If you await the SendAsync call you'll get a HttpResponseMessage object you can get the status code from:
Also, wrap your IDisposable objects in using() blocks (except HttpClient - which should be a static singleton or better yet, use IHttpClientFactory).
Don't use HttpClient.DefaultRequestHeaders for request-specific headers, use HttpRequestMessage.Headers instead.
The Connection: Keep-alive header will be sent by HttpClientHandler automatically for you.
Are you sure you need to send Cache-control: no-cache in the request? If you're using HTTPS then it's almost guaranteed that there won't be any proxy-caches causing any issues - and HttpClient does not use the Windows Internet Cache either.
Don't use Encoding.UTF8 because it adds a leading byte-order-mark. Use a private UTF8Encoding instance instead.
Always use .ConfigureAwait(false) with every await on code that does not run in a thread-sensitive context (such as WinForms and WPF).
private static readonly HttpClient _httpClient = new HttpClient();
private static readonly UTF8Encoding _utf8 = new UTF8Encoding( encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true );
static async Task CreateConsentAsync( Uri uri, ConsentHeaders cconsentHeaders, ConsentBody cconsent )
{
using( HttpRequestMessage req = new HttpRequestMessage( HttpMethod.Post, uri ) )
{
req.Headers.Accept.Add( new MediaTypeWithQualityHeaderValue("*/*") );
req.Headers.Add("Cache-Control", "no-cache");
req.Headers.Add("otherHeader", myValue);
//etc. more headers added, as needed...
String jsonObject = JsonConvert.SerializeObject( cconsent, Formatting.Indented );
request.Content = new StringContent( jsonObject, _utf8, "application/json");
using( HttpResponseMessage response = await _httpClient.SendAsync( request ).ConfigureAwait(false) )
{
Int32 responseHttpStatusCode = (Int32)response.StatusCode;
Console.WriteLine( "Got response: HTTP status: {0} ({1})", response.StatusCode, responseHttpStatusCode );
}
}
}

You could simply check the StatusCode property of the response:
https://learn.microsoft.com/en-us/previous-versions/visualstudio/hh159080(v=vs.118)?redirectedfrom=MSDN
static async void dotest(string url)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode.ToString());
}
else
{
// problems handling here
Console.WriteLine(
"Error occurred, the status code is: {0}",
response.StatusCode
);
}
}
}

#AthanasiosKataras is correct for returning the status code itself but if you would also like to return the status code value (ie 200, 404). You can do the following:
var response = await client.SendAsync(request);
int statusCode = (int)response.StatusCode
The above will give you the int 200.
EDIT:
Is there no reason why you cannot do the following?
using (HttpResponseMessage response = await client.SendAsync(request))
{
// code
int code = (int)response.StatusCode;
}

Related

How can I make a discord timeout command with discord.net C#

Im trying to make a Discord C# Command That uses Discords new Timeout function using discord.NET
I tried using HTTP Requests instead cause i couldnt find a discord.NET function but It returns an unauthorized error
public static async Task PatchData(string url, string data, string token)
{
// Create a new HttpClient instance
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Authorization",token);
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var content = new StringContent(data, Encoding.UTF8, "application/json");
var response = await httpClient.PatchAsync(url, content);
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Data patched successfully!");
}
else
{
Console.WriteLine(response.StatusCode);
}
}
and for the execution
await Patch.PatchData($"https://discord.com/api/v9/guilds/{Context.Guild.Id}/members/{user.Id}",
"{\"communication_disabled_until\": "
+ current_time + time_in_minutes + "}",botToken);

Error Creating Folder in Sharepoint using REST API C#

I can accomplish all other tasks with the rest API, like uploading and downloading files, navigating through the file directory. I just keep getting either 400 Bad Request or sometimes with some tries I'll get 500 Internal Server Error. Also, I can create the request on postman and its successful
this is what the request should look like the rest is me creating it in c#
POST https://{site_url}/_api/web/folders
Authorization: "Bearer " + accessToken
Accept: "application/json;odata=verbose"
Content-Type: "application/json"
Content-Length: {length of request body as integer}
X-RequestDigest: "{form_digest_value}"
{
"__metadata": {
"type": "SP.Folder"
},
"ServerRelativeUrl": "/document library relative url/folder name"
}
private async Task PostFolderSharePoint(string url, string serverRelativeUrl)
{
string accessToken = GetAccessToken().GetAwaiter().GetResult();
string jsoncontent = JsonConvert.SerializeObject("{\"__metadata\": {\"type\": \"SP.Folder\"},\"ServerRelativeUrl\": serverRelativeUrl}");
var content = new StringContent(jsoncontent, Encoding.UTF8, "application/json");
var FormDiGestValue = await GetFormDigestValue(accessToken);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var requestMessage = new HttpRequestMessage(HttpMethod.Post,url) { Content = content };
requestMessage.Headers.Add("X-RequestDigest", FormDiGestValue);
HttpResponseMessage response = await _httpClient.SendAsync(requestMessage).ConfigureAwait(false);
return response;
}
This is how I create a folder with the Sharepoint REST API:
public async Task<string> CreateFolder(string folderName, string relativeUrl)
{
try
{
var url = "https://your.sharepoint.com/sites/devsite/_api/web/folders";
var json = "{\"ServerRelativeUrl\": \"" + relativeUrl + "/" + folderName + "\"}";
var payload = new StringContent(json, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-User-Agent", "spoc");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
var response = await client.PostAsync(url, payload);
return await response.Content.ReadAsStringAsync();
}
catch (WebException we)
{
throw new SomethingException(we);
}
}
and to use it:
var modFolder = await spocRest.CreateFolder("MOD1", "Shared Documents");

How to pass request content with HttpClient GetAsync method in c#

How do I pass request content in the HttpClient.GetAsync method? I need to fetch data depending upon request content.
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch()
{
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch");
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
If you are using .NET Core, the standard HttpClient can do this out-of-the-box. For example, to send a GET request with a JSON body:
HttpClient client = ...
...
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("some url"),
Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
If you want to send content, then you need to send it as query string (According to your API route)
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch/paramname=<dynamicName>&paramValue=<dynamicValue>");
And in API check for "paramName" and "paramValue"
this works for me:
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("your url"),
Content = new StringContent("your json", Encoding.UTF8, ContentType.Json),
};
using (var response = await httpClient.SendAsync(request))
{
string apiResponse = await response.Content.ReadAsStringAsync();
}
}
EDITED:
This is minor different then #SonaliJain answer above:
MediaTypeNames.Application.Json instead of ContentType.Json
I'm assuming that your "request content" would be POST data, no?
If you're sending it using the standard form content way of doing it, you would first have to build the content:
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", "theperplexedone"),
new KeyValuePair<string, string>("password", "mypassword123"),
});
And then submit it using PostAsync instead:
var response = await client.PostAsync("http://localhost:8080/document/quicksearch", content);
Hi all thank you for your comments, i got the solution
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch(HttpRequestMessage Query)
{
Debugger.Launch();
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
Console.WriteLine(Query);
HttpResponseMessage response = await client.GetAsync("http://localhost:8080/document/quicksearch/"+ Query.RequestUri.Query);
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
else
{
Console.Write("Failure");
}
return response;
}
}
catch (Exception e)
{
throw e;
}

How to reset settings in c# httpClient?

In c#, I make get and post requests. This is my code
GET
private async Task<string> GetAsync(string uri, Token token, string accept, string content_type)
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept)); // ACCEPT header
bool added = client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "text/xml");
if (token != null) client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token.token_type, token.access_token);
HttpResponseMessage g = await client.GetAsync(uri);
if (g.IsSuccessStatusCode)
{
return await g.Content.ReadAsStringAsync();
}
else
{
errors.AddError(g.ReasonPhrase, await g.Content.ReadAsStringAsync());
return null;
}
}
POST
private async Task<string> PostAsync(string uri, Token token, string postData, string accept, string content_type)
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept)); // ACCEPT header
if (token != null) client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token.token_type, token.access_token);
var content = new StringContent(postData, Encoding.UTF8, content_type);
HttpResponseMessage g = await client.PostAsync(uri, content);
if (g.IsSuccessStatusCode)
{
return await g.Content.ReadAsStringAsync();
}
else
{
errors.AddError(g.ReasonPhrase, await g.Content.ReadAsStringAsync());
return null;
}
}
But I read that you should reuse the httpclient like this
private static HttpClient client = new HttpClient();
as I make lots of frequent requests. However if I re-use the object, the settings like headers persist and that causes issues. Is there a way I can just reset the settings but keep the object?
Thanks
Don't use the HttpClient's default headers. Set the headers on the request:
var content = new StringContent(postData, Encoding.UTF8, content_type) // CONTENT-TYPE header
content.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(accept)); // ACCEPT header
if (token != null)
content.Headers.Authorization = new AuthenticationHeaderValue(token.token_type, token.access_token);
Then all threads can use the same HttpClient throughout the runtime of the application without issue.

Asynchronous HTTP Response Message

so this has been bugging since a while. I am not sure why my Http Response Message step is skipped by Visual Studio Debugger. This is the code i have currently:
public async void APIcall()
{
HttpClient httpClient = new HttpClient();
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://xxxx");
requestMessage.Headers.Add("Accept", "application/json");
requestMessage.Headers.Add("ContentType", "application/json");
requestMessage.Headers.Add("RequestMessageGUID", "xxxxxx");
HttpResponseMessage response = await httpClient.SendAsync(requestMessage);
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
Console.ReadLine();
}
Please give your suggestions and help to resolve this.
First, you should avoid doing async on void methods unless it's an event handler. Use Task even if you are not returning anything.
Next you are assuming that you will always get content from your request.
You should check first that there is something to get
When you use async on void methods your exceptions are not going to get caught. That is probably why it kept skipping as you said. It was probably error out.
private static HttpClient httpClient = new HttpClient();
public async Task APIcall() {
try {
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://xxxx");
requestMessage.Headers.Add("Accept", "application/json");
requestMessage.Headers.Add("ContentType", "application/json");
requestMessage.Headers.Add("RequestMessageGUID", "xxxxxx");
HttpResponseMessage response = await httpClient.SendAsync(requestMessage);
if (response.Content.Headers.ContentLength.GetValueOrDefault() > 0) {
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
} else {
Console.WriteLine(response.StatusCode);
}
} catch(Exception ex) {
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}

Categories

Resources