How to get and print response from Httpclient.SendAsync call - c#

I'm trying to get a response from a HTTP request but i seem to be unable to. I have tried the following:
public Form1() {
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("someUrl");
string content = "someJsonString";
HttpRequestMessage sendRequest = new HttpRequestMessage(HttpMethod.Post, client.BaseAddress);
sendRequest.Content = new StringContent(content,
Encoding.UTF8,
"application/json");
Send message with:
...
client.SendAsync(sendRequest).ContinueWith(responseTask =>
{
Console.WriteLine("Response: {0}", responseTask.Result);
});
} // end public Form1()
With this code, i get back the status code and some header info, but i do not get back the response itself. I have tried also:
HttpResponseMessage response = await client.SendAsync(sendRequest);
but I'm then told to create a async method like the following to make it work
private async Task<string> send(HttpClient client, HttpRequestMessage msg)
{
HttpResponseMessage response = await client.SendAsync(msg);
string rep = await response.Content.ReadAsStringAsync();
}
Is this the preferred way to send a 'HttpRequest', obtain and print the response? I'm unsure what method is the right one.

here is a way to use HttpClient, and this should read the response of the request, in case the request return status 200, (the request is not BadRequest or NotAuthorized)
string url = 'your url here';
// usually you create on HttpClient per Application (it is the best practice)
HttpClient client = new HttpClient();
using (HttpResponseMessage response = client.GetAsync(url).GetAwaiter().GetResult())
{
using (HttpContent content = response.Content)
{
var json = content.ReadAsStringAsync().GetAwaiter().GetResult();
}
}
and for full details and to see how to use async/await with HttpClient you could read the details of this answer

Related

API HTTP client returning data

I am working on this helper method that will call an API using the body section. I am passing in the url and data in the model. Then I SerializeObject the model, but I am not sure what to return I get the error message about the response.Content is not found.
public static async System.Threading.Tasks.Task<HttpResponse> HttpClientHandlerAsync(string url, object model)
{
var fullUrl = apiUrl + url;
var json = JsonConvert.SerializeObject(model);
var data = new StringContent(json, Encoding.UTF8, "application/json");
Client.DefaultRequestHeaders.Add("Accept", "*/*");
Client.DefaultRequestHeaders.Authorization
= new AuthenticationHeaderValue("Bearer", "token");
var response = await Client.PostAsync(fullUrl, data);
return response;
}
Add await in front of your
await Client.PostAsync(fullUrl, data);
Because you're trying to get content of Task
I am not sure what to return I get the error message about the response.Content is not found.
Set a breakpoint and hover over the response to see the status code. You could have a 500 server error, authentication error etc.
Furthermore
using (var client = new HttpClient())
Do not do this. It doesn't work the way you think it does, it will starve your connection pool and eventually throw an exception. You need to define the HttpClient somewhere and continue to reuse the same instance.
Further reading if you care https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

Why is my HTTP POST Body content received/processed as NULL?

I want to be able to receive the Body content of a POST request inside the POST function definition in the REST API.
I have a client code that converts a C# object into JSON and then wraps it in a HTTP StringContent. This payload is then sent via a HTTP Post request to the URL. However the Post method in API always returns NULL when I try returning the received string.
Client:
public async void Register_Clicked(object sender, EventArgs e) // When user enters the Register button
{
Sjson = JsonConvert.SerializeObject(signup);
var httpContent = new StringContent(Sjson);
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("https://apiname.azurewebsites.net");
var response = await client.PostAsync("api/values", httpContent);
var responseContent = await response.Content.ReadAsStringAsync();
StatusLabel.Text = responseContent; //To display response in client
}
}
API POST Definition:
[SwaggerOperation("Create")]
[SwaggerResponse(HttpStatusCode.Created)]
public string Post([FromBody]string signup)
{
return signup;
}
I want the clients input back as a response to be displayed in the client (StatusLabel.Text). However all I receive is NULL. Kindly guide me in the right direction.
I have prepared a simple example on how you can retrieve your Result from your Task:
async Task<string> GetResponseString(SigupModel signup)
{
Sjson = JsonConvert.SerializeObject(signup);
var httpContent = new StringContent(Sjson);
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("https://apiname.azurewebsites.net");
var response = await client.PostAsync("api/values", httpContent);
var responseContent = await response.Content.ReadAsStringAsync();
}
return responseContent;
}
And you can call this as:
Task<string> result = GetResponseString(signup);
var finalResult = result.Result;
StatusLabel.Text = finalResult; //To display response in client
If you are not using async keyword, then you can call get your Result as:
var responseContent = response.Content.ReadAsStringAsync().Result;
EDIT
Basically you would have to POST your signup model to your API Controller. Use SigupModel signup as a parameter if you would like. Then whatever processing you are doing in the API, the final result in a string. Now this string can either be a null, empty or have a value. When you get this value in your client, you would have do the following:
var responseContent = await response.Content.ReadAsStringAsync();
var message = JsonConvert.DeserializeObject<string>(responseContent);
Here you will get your message a string and then you can set it as: StatusLabel.Text = message ;

Send http get with request body c#

I want to send an HTTP GET with a request body. I know there is much heated debate about whether this should ever be done or not but I am not interested in debating it I simply want to do it. I'm using C# and ASP.NET and my code is below. Unfortunately it throws an exception "Cannot send a content-body with this verb type". Please, any help on how to get this done will be very appreciated!
// Serialize our concrete class into a JSON String
var stringPayload = JsonConvert.SerializeObject(memRequest);
// Wrap our JSON inside a StringContent which then can be used by the HttpClient class
var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json");
using (var httpClient = new HttpClient())
{
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = u,
Content = httpContent
};
var result = httpClient.SendAsync(request).Result;
result.EnsureSuccessStatusCode();
var responseBody = result.Content.ReadAsStringAsync().ConfigureAwait(false);

C# Web API - POST Request doesn't get executed

I am trying to send a POST request from my ASP.NET Core Web API Project but the request is never sent. The method gets executed with no errors but the request never gets sent out from the async method.
My Implementation:
public async void notify(String message)
{
String url = "MY_WEBSERVICE_URL";
var client = new HttpClient();
client.BaseAddress = new Uri(url);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "relativeAddress");
request.Content = new StringContent("application/x-www-form-urlencoded;charset=UTF-8",
Encoding.UTF8, "application/json");
Byte[] byteArray = Encoding.UTF8.GetBytes("{\"text\":\"" + message + "\"}");
request.Content.Headers.ContentLength = byteArray.Length;
await client.SendAsync(request).ContinueWith(responseTask =>
{
Console.WriteLine("Response: {0}", responseTask.Result);
});
}
Is this the proper way of making a POST request from a Core Web API project? Thank you in advance
First of all, there is a dedicated method PostAsync in the HttpClient class ( or even PostAsJsonAsync extension) which you can use to send POST requests without creating HttpRequstMessage manually.
Now about your code - I believe you want to post following JSON string:
{"text":"someMessage"}
You should set this string as a content of StringContent which you are sending:
var json = "{\"text\":\"" + message + "\"}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
Currently you are trying to post mediatype string as a value to your API endpoint. Of course it cannot be deserialized into your model.
Note1: StringContent will automatically add Content-Length header with the appropriate value. You should not do that manually.
Note2: Unless this is an event handler, you should not use async void - use async Task instead.
Same task with PostAsJsonAsync usage will look like:
public async Task Notify(string message)
{
var string url = "MY_WEBSERVICE_URL";
var client = new HttpClient();
client.BaseAddress = new Uri(url);
var notification = new Notification { Text = message }; // use some model class
var resonse = await client.PostAsJsonAsync("relativeAddress", notification);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
}
}
In this case, your model will be automatically serialized into JSON, appropriate content will be created and POST request will be sent.
Try Adding [IgnoreAntiforgeryToken] on top of the Post Action like this

Retrieve POST Request Body of Http client in C#

Any way to retrieve the POST Request Body of Http Client in C#? I just want to check in my UT if my extension method is adding it properly to the request or not. This function is not doing any justice to it.
public static async Task<string> AddPostRequestBody<T>(this HttpClient httpclient, string RequestUrl, T classobject)
{
string json_body = Newtonsoft.Json.JsonConvert.SerializeObject(classobject);
HttpRequestMessage RequestMessage = new HttpRequestMessage(HttpMethod.Post, RequestUrl);
HttpResponseMessage response = await httpclient.PostAsync(RequestUrl, new StringContent(json_body));
response = httpclient.SendAsync(RequestMessage).Result;
string outputresult = await response.RequestMessage.Content.ReadAsStringAsync();
return outputresult;
}
Please help !
Try using a DelegatingHandler (which I've used in implementing HMAC to hash the content and add the necessary authorization headers), this will let you access the content.
CustomDelegatingHandler customDelegatingHandler = new CustomDelegatingHandler();
HttpClient client = HttpClientFactory.Create(customDelegatingHandler);
public class CustomDelegatingHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Content != null)
{
byte[] content = await request.Content.ReadAsByteArrayAsync();
// Do what you need with the content here
}
response = await base.SendAsync(request, cancellationToken);
return response;
}
}
Okay so I got it working with this instead of creating a response, I am directly appending to the request message and retrieving from it. Simple one but initially in the posted question, I made it complicated by adding the json string to response.
public static string AddPostRequestBody<T>(this HttpClient httpclient, string requestUrl, T classObject)
{
string jsonBody = Newtonsoft.Json.JsonConvert.SerializeObject(classObject);
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, requestUrl);
requestMessage.Content = new StringContent(jsonBody);
string requestBody = requestMessage.Content.ReadAsStringAsync().Result;
return requestBody;
}

Categories

Resources