HttpClient.DeleteAsync and Content.ReadAdStringAsync always return null - c#

When I'm using DeleteAsync function in HttpClient (System.Net.Http) and retrieve the content with Content.ReadAsStringAsync() I always get null returned.
I've tried the same with GET, POST and PUT - and they always return some result.
Here is my code:
HttpClient _client = new HttpClient();
_client.BaseAddress = new Uri("http://httpbin.org/");
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = _client.DeleteAsync("/delete").Result;
string res = await response.Content.ReadAsStringAsync();
return await JsonConvert.DeserializeObjectAsync<T>(res);
I always get null returned.
However, all of this works:
GET:
HttpResponseMessage response = _client.GetAsync("/get").Result;
string res = await response.Content.ReadAsStringAsync();
return await JsonConvert.DeserializeObjectAsync<T>(res);
POST:
HttpResponseMessage response = _client.PostAsync("/post", new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json")).Result;
string res = await response.Content.ReadAsStringAsync();
return await JsonConvert.DeserializeObjectAsync<T>(res);
PUT:
HttpResponseMessage response = _client.PutAsync("/put", new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json")).Result;
string res = await response.Content.ReadAsStringAsync();
return await JsonConvert.DeserializeObjectAsync<T>(res);
But DeleteAsync() and ReadAsStringAsync() always return me null.
According to RFC you have to return body when returning status code 200 OK.

Your code never checks the message response for the StatusCode. Unlike WebClient, HttpClient does NOT throw when the StatusCode is not in the 2xx range.
I bet that if you check the HttpResponseMessage.StatusCode/HttpResonseMessage.ReasonPhrase values you will find that the server returned a code other than 200.
For example:
HttpClient _client = new HttpClient();
_client.BaseAddress = new Uri("http://httpbin.org/");
...
var response = await _client.DeleteAsync("/delete");
if (response.IsSuccessStatusCode)
{
var result=await response.Content.ReadAsStringAsync();
....
}
You can also call the EnsureSuccessStatusCode method to throw an exception if the response status is not a success code:
HttpClient _client = new HttpClient();
_client.BaseAddress = new Uri("http://httpbin.org/");
...
var response = await _client.DeleteAsync("/delete");
response.EnsureSuccessStatusCode();
var result=await response.Content.ReadAsStringAsync();
EDIT
By the way, running the following as is on .NET 4.5, returns a body:
var _client = new HttpClient();
_client.BaseAddress = new Uri("http://httpbin.org/");
var response = await _client.DeleteAsync("/delete");
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
Adding the Accept header doesn't make any difference

I have same case... for now I dont know method overload for DeleteAsync which accept content parameters like post. So I switch API from Delete to Post.

Do you know:
base_address + relative_address
"http://www.youdomain.com/myservice/" + "/test" = "/test".
This is why you get nothing

Related

POST an empty body via HTTP Client

I am trying to send an empty body to a Post Request but it does not execute.
I have already tried this:
Post an empty body to REST API via HttpClient
static async Task<string> CancelSale(string mainUrl, string bearerInfo,string systemNumber)
{
var cancelsaleUrl = mainUrl + $"api/sale/cancel/{systemNumber}";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerInfo);
var data = new StringContent(null, Encoding.UTF8, "application/json");
var saleResponse = await client.PostAsync(cancelsaleUrl, data);
var responseBody = await saleResponse.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
return responseBody;
}
But it just does not execute, no exception.
I also tried this :
var saleResponse = await client.PostAsync(cancelsaleUrl, null);
which also does the same result.
Any ideas?
The problem was very simple. I had the result of whole this method in a variable and It did not await the method:
var cancelSale = CancelSale(mainUrl, bearerInfo, systemNumber);
Once it reaches anything that awaits it stops and leaves the method.
Here is the working code:
var cancelSale = await CancelSale(mainUrl, bearerInfo, systemNumber);
static async Task<string> CancelSale(string mainUrl, string bearerInfo,string systemNumber)
{
var cancelsaleUrl = mainUrl + $"api/sale/cancel/{systemNumber}";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerInfo);
var saleResponse = await client.PostAsync(cancelsaleUrl, null);
var responseBody = await saleResponse.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
return responseBody;
}

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 convert response of post request to bool in c#?

I have an endpoint in my ASP.NET Core 2.1 Controller
[HttpPost]
public async Task<bool> CheckStatus([FromBody] StatusModel model)
{
...code ommited
return true;
}
And I call this endpoint from other place in code like this:
await client.PostAsync('/CheckStatus', payloayd)
How can I retrive a bool value from this request?
Using Newtonsoft.Json, you can read the response of the request and parse it into a bool.
using Newtonsoft.Json;
public async Task<bool> GetBooleanAsync()
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var data = new { };
var url = "my site url";
var payload = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
var req = await client.PostAsync(url, payload);
var response = await req.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<bool>(response);
}
}
UPDATE
Looking back on this from a few years on, this can be simplified without the use of Newtonsoft.Json to read the response, by simply parsing the string data to a boolean.
public async Task<bool> GetBooleanAsync()
{
var data = new { };
var url = "my site url";
var payload = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
using var client = new HttpClient();
var response = await client.PostAsync(url, payload);
var data = await response.Content.ReadAsStringAsync();
return boolean.Parse(data);
}
However, if your boolean value is returned in a JSON object, then Newtonsoft.Json could be used to read that value.

Call REST Service from WebAPi and transfer HttpResponseMessage

I have to call a REST Service from Web API.
Call and retrieve data works well but the return method crash.
I have tried several method that return an async HttpResponseMessage, but I can return this object as well (error socket on chrome ERR_SPDY_PROTOCOL_ERROR).
I've tried too with just a plain json as string, but no more success.
Here some tries :
[Route("{id}")]
public async Task<JObject> Get(string id)
{
dynamic client = new RestClient($"https://...../accounts/{id}/summary",
new Dictionary<string, string> {
//some KVP for access Rest API
});
//await client.Get() returns HttpResponseMessage 200 and Content is well populated
JObject result = JObject.FromObject(await client.Get());
return result;
//Request.CreateResponse(HttpStatusCode.OK, await result.Content.ReadAsAsync<string>());
//HttpResponseMessage result = await client.Get(); => HttpResponseMessage is well filled
//Request.CreateResponse(HttpStatusCode.OK, await result.Content.ReadAsAsync<string>()); => test with wrapping inside a new HttpResponseMessage but no more success
//using (var client = new HttpClient())
//{
// client.BaseAddress = new Uri($"https://....../v1/accounts/{id}/summary");
// client.DefaultRequestHeaders.Accept.Clear();
// client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HttpResponseMessage response = await client.GetAsync("");
// return Request.CreateResponse(HttpStatusCode.OK, response.Content.ReadAsAsync());
//}
}
Is there a simple method to retrieve json from Rest Service and transfer this as it is ?
If these calls are being performed in a Web API, and there is no logic being applied to the JSON Object, then there is little need to parse it before returning it as it will get serialized again when being returned, you can instead parse it on the front-end application and perform your logic there.
HttpClient has a method which returns the response body as a string, this is GetStringAsync. With the body returned as string, you can return that directly in your HttpResponseMessage
Here's an example using your HttpClient commented code.
[Route("{id}")]
public async Task<HttpResponseMessage> Get(string id)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri($"https://....../v1/accounts/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Fetch the response body as a string
// Resource URI added below
string responseContent = await client.GetStringAsync($"{id}/summary");
// Create our response object and set the content to its StringContent
var response =
new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent(responseContent)};
// Return our HttpResponseMessage containing our json text
return response;
}
}
If you just want to transfer the json response from another API, you can use code like the following in Web API:
[HttpGet]
[Route("v1/test", Name = "test")]
public HttpResponseMessage GetTest()
{
UriBuilder uriBuilder = new UriBuilder($"https://...../...");
var webRequest = (HttpWebRequest)WebRequest.Create(uriBuilder.Uri);
webRequest.Method = "GET";
webRequest.ContentType = "application/json; charset=utf-8";
webRequest.Accept = "application/json, text/javascript, */*";
using (var jsonResponse = (HttpWebResponse) webRequest.GetResponse())
{
var jsonStream = jsonResponse.GetResponseStream();
MemoryStream ms = new MemoryStream();
jsonStream.CopyTo(ms);
ms.Position = 0;
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(ms);
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
return response;
}
}
When the only thing needed is to support authentication or authorization features, i would prefer to use an API manager and not maintain this kind of code myself.

C#: Error when HttpClient reponse

I am doing HTTP get request using HttpClient in C# console app . I am not getting expected response with one get request.
Get Request is like
http://example.com/xyz/SearchProduct?productNo=11210&1d6rstc9xc=5jyi27htzk
I am getting some vague response but when i do same get request with fiddler it is giving expected response.
How can I get expected response from httpClient.GetAsync(url)?
code is :-
var httpClient = new HttpClient();
var url = "http://example.com/xyz/SearchProduct?productNo=11210&1d6rstc9xc=5jyi27htzk";
HttpResponseMessage response1 = await httpClient.GetAsync(url);
if (response1.IsSuccessStatusCode)
{
HttpContent stream = response1.Content;
Task<string> data = stream.ReadAsStringAsync();
}
You should read as string that way:
string result = await stream.ReadAsStringAsync();
instead of that:
Task<string> data = stream.ReadAsStringAsync();
Here full code example and another example
This is a full method using async/await approach.
private static async Task<string> GetRequestContentAsString(string url)
{
var data = string.Empty;
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var stream = response.Content;
data = await stream.ReadAsStringAsync();
}
}
return data;
}
This method is called this way:
var content = await GetRequestContentAsString("http://www.bing.com");

Categories

Resources