How to read/output response from the HTTP request - c#

I send HTTP request to a webpage to insert or retrieve data.
This is my code:
string json = JsonConvert.SerializeObject(user);
using (var client = new HttpClient())
{
var response = client.PostAsync(
"url",
new StringContent(json, Encoding.UTF8, "application/json"));
}
DisplayAlert("Alert", json, "OK");
DisplayAlert("test", response, "test");
For this particular example; the website should return true or false.
But I want to read the response variable.
The DisplayAlert("test", response, "test"); show error. And this is because I am trying to read response outside of scope.
My question is how to read the response variable or output response variable on the page?
Edit
{
LoginModel user = new LoginModel();
{
user.email = email.Text;
user.password = password.Text;
};
string json = JsonConvert.SerializeObject(user);
using (var client = new HttpClient())
{
}
var response = client.PostAsync(
"https://scs.agsigns.co.uk/tasks/photoapi/login-photoapi/login-check.php",
new StringContent(json, Encoding.UTF8, "application/json"));
DisplayAlert("Alert", json, "OK");
DisplayAlert("test", response, "test");
}

This gives you an error because you try to access a variable which is declared inside of a different scope. If you move the variable response inside of the "method scope" the error will disappear:
string json = JsonConvert.SerializeObject(user);
HttpResponseMessage response;
using (var client = new HttpClient())
{
response = await client.PostAsync(
"url",
new StringContent(json, Encoding.UTF8, "application/json"));
}
DisplayAlert("Alert", json, "OK");
DisplayAlert("test", await response.Content.ReadAsStringAsync(), "test");
Note the await which I added just before client.PostAsync() (You will find more infos about async/await in the docs).
To get the string representation of the response content you can use following method:
await response.Content.ReadAsStringAsync();
This will read the response content as string.

string json = JsonConvert.SerializeObject(user);
HttpResponseMessage response;
using (var client = new HttpClient())
{
response = client.PostAsync(
"url",
new StringContent(json, Encoding.UTF8, "application/json").Result);
}
var body = response.Content.ReadAsStringAsync().Result;
DisplayAlert("Alert", json, "OK");
DisplayAlert("test", body, "test");
should work, by moving the declaration of the variable outside the scope, and updating the value inside the call.

Related

HttpClient request no response

I am not getting any response - no error, no bad request status, etc. - when I send a post request to this API route. postData is simply a JSON object. The funny thing here is this: When i send post data as a string instead of an object, I can get a response.
View the code below:
[HttpPost]
[Route("api/updateStaffs/")]
public async Task<object> UpdateStaff([FromBody] object postData)
{
string _apiUrl = "http://localhost:5000/system/getToken";
string _baseAddress = "http://localhost:5000/system/getToken";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_baseAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var responseMessage = await client.PostAsync(_apiUrl, new StringContent(postData.ToString(), Encoding.UTF8, "application/json"));
if (responseMessage.IsSuccessStatusCode)
{
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = responseMessage.Content;
return ResponseMessage(response);
}
}
return NotFound();
}
No response:
var postData = new {
user = "test"
pass = "hey"
};
var responseMessage = await client.PostAsync(_apiUrl, new StringContent(postData.ToString(), Encoding.UTF8, "application/json"));
OR
var responseMessage = await client.PostAsync(_apiUrl, new StringContent("{}", Encoding.UTF8, "application/json"));
Will get response:
var responseMessage = await client.PostAsync(_apiUrl, new StringContent("blahblah", Encoding.UTF8, "application/json"));
The receiving API is a third-party application so I am unable to verify if this error is on the other end.
Thanks.
If you dont want to use PostAsJsonAsync
You need to serialize your anonymous type to JSON, the most common tool for this is Json.NET
var jsonData = JsonConvert.SerializeObject(postData);
Then you need to construct a content object to send this data, here we can use ByteArrayContent but you can use a different type
var buffer = System.Text.Encoding.UTF8.GetBytes(jsonData);
var byteContent = new ByteArrayContent(buffer);
Then send the request
var responseMessage = await client.PostAsync(_apiUrl, byteContent);
Figured out the issue. Have to use HttpVersion10 instead of HttpVersion11.

why An error is created when creating the token

public static void CreateToken()
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("grant_type", "client_credentials");
var UserPassJson = "{\"username\": \"mucode\",\"password\": \"mypassword\"}";
HttpContent content = new StringContent(UserPassJson, Encoding.UTF8, "application/json");
var response = client.PostAsync(new Uri("https://api.sandbox.paypal.com/v1/oauth2/token"), content).Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
string responseString = responseContent.ReadAsStringAsync().Result;
Console.WriteLine(responseString);
}
}
why response.IsSuccessStatusCode Showing status code 401? What causes the malfunction?
What action does cause success?
The documentation specifies that you should pass the username and password using basic authentication and that you should pass a form-encoded body containing grant_type=client_credentials.
At the moment your code adds grant_type as a header, and posts the username and password as a JSON object in the body.
Correcting your code to do it the way the documentation says, we get:
HttpClient client = new HttpClient();
byte[] authBytes = System.Text.Encoding.ASCII.GetBytes("mucode:mypassword");
string base64Auth = Convert.ToBase64String(authBytes);
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", base64Auth);
HttpContent content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("grant_type", "client_credentials") });
var response = client.PostAsync(new Uri("https://api.sandbox.paypal.com/v1/oauth2/token"), content).Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
string responseString = responseContent.ReadAsStringAsync().Result;
Console.WriteLine(responseString);
}
P.S. I recommend reading You're using HttpClient wrong and it is destabilizing your software and the follow-up You're (probably still) using HttpClient wrong and it is destabilizing your software. I also recommend making this method async and making the chain all the way up async too.

Strange behavior in HttpRequestMessage's Content-Type header

I tried to make HTTP POST request with application/json in body to an external web-service from C# (.NET Core 2.2.104).
I've already read all similar questions in SO and wrote this code:
SignXmlRequestDto requestBody = new SignXmlRequestDto(p12, model.SignCertPin, model.Data);
string json = JsonConvert.SerializeObject(requestBody);
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = ncanNodeUrl,
Headers =
{
{ HttpRequestHeader.ContentType.ToString(), "application/json" }
},
Content = new StringContent(JsonConvert.SerializeObject(json))
};
var response = await httpClient.SendAsync(httpRequestMessage);
string responseString = await response.Content.ReadAsStringAsync();
I am getting an error from service, it says: "Invalid header Content-Type. Please set Content-Type to application/json". What is interesting here, if I simulate this request from Postman, then everything work well and I get successful response.
Updated: as #Kristóf Tóth suggested, I modified my code to:
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = ncanNodeUrl,
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
var response = await httpClient.SendAsync(httpRequestMessage);
string responseString = await response.Content.ReadAsStringAsync();
but it still gives me the same error message.
Content-Type is a content header. It should be set on the content, not the request itself. This can be done either using the StringContent(string,Encoding,string) constructor :
Content = new StringContent(JsonConvert.SerializeObject(json),Encoding.UTF8, "application/json")
or by setting the StringContent's Headers.ContentType property :
var content=new StringContent(JsonConvert.SerializeObject(json));
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
This might be an encoding issue. You should use JsonContent not StringContent OR you can do something similar:
// Serialize into JSON String
var stringPayload = JsonConvert.SerializeObject(payload);
// Wrap JSON StringContent which then can be used by the HttpClient class
var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json");

Cant get Authorized with my API that has a JWT authentication Im Working With Xamarin

Well Im new in Xamarin and I'm developing and App, the authentication is JWT based.
Im using a HttpClient and setting the AuthenticationHeaders but It always returns Unauthorized when I try it on Postman it Works but I can't make it work in my app.
Here is how im trying to do it:
var client = new HttpClient(new HttpClientHandler());
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("JWT", accessToken);
client.BaseAddress = new Uri(urlBase);
var url = string.Format("{0}{1}", servicePrefix, controller);
var response = await client.GetAsync(url);
Try something like this
using (var client = new HttpClient())
{
var uri = new Uri(string.Format($"{<yourURLString>}", string.Empty));
var jsonTransport = "";
var jsonPayload = new StringContent(jsonTransport, Encoding.UTF8, "application/json");
//client.DefaultRequestHeaders.Add("Content-type", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "JWT " + accessToken);
var response = await client.PostAsync(uri, jsonPayload);
string responseContent = await response.Content.ReadAsStringAsync();
}
then deserialize the responseContent to your object using JsonConvert.DeserializeObject
Note: Below are code samples, edit to your own objects
SubscriptionResponse profileResponse = JsonConvert.DeserializeObject<SubscriptionResponse>(responseContent);
then if your method returns something, use the return statement. Something like this
return profileResponse.Data.Subscriptions;
If you're using a get, this could be a guide
var uri = new Uri(string.Format($"{<yourURLHere>}", string.Empty));
client.DefaultRequestHeaders.Add("Authorization", "JWT " + accessToken);
var httpResponse = await client.GetAsync(uri);
var responseContent = await httpResponse.Content.ReadAsStringAsync();
then deserialize your string response
Note: this is a sample - edit to your model (You may use PostMan to get the response format in JSON and model it in C#)
var UserDetailResponse = JsonConvert.DeserializeObject<UserDetail>(responseContent);
return UserDetailResponse;

Post call for xml content using HttpClient

How to make xml content compatible with HttpClient's PostAsync operation for the content and where do you specify the headers for Content-Type = application/xml.
Error -> Cannot convert string to HttpContent
public async Task GetCustomersAsync(string firstname, string lastname)
{
using (var client = new HttpClient())
{
var content = "<soapenv:Envelope xmlns:xsi...";
var response = await client.PostAsync("https://domain.com/scripts/WebObj.exe/Client.woa/2/ws/ABC", content);
var responseString = await response.Content.ReadAsStringAsync();
}
}
My guess is what you want to do is the following:
public async Task<string> GetCustomersAsync(string firstname, string lastname)
{
using (var client = new HttpClient())
{
var content = new StringContent("<soapenv:Envelope xmlns:xsi...", Encoding.UTF8, "application/xml");;
var response = await client.PostAsync("https://example.com/scripts/WebObj.exe/Client.woa/2/ws/ABC", content);
return await response.Content.ReadAsStringAsync();
}
}
OR
using (var request = new HttpRequestMessage { RequesteUri = new Uri("POST_URL"), Method = HttpMethod.Post })
{
var content = new StringContent("<soapenv:Envelope xmlns:xsi...");
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
}
You can refer here to more information about other Content types that can be created and passed.
To specifically request xml content in response you must define the content type in the header of the content. The MediaTypeHeaderValue is parsed and set in the ContentType property of the content Headers. Here is a complete example of the code;
using (var client = new HttpClient())
{
var content = new StringContent(messageToPOST, Encoding.UTF8, "text/xml");
content.Headers.ContentType = MediaTypeHeaderValue.Parse("text/xml");
response = await client.PostAsync(_uri, content);
responseMsg = await response.Content.ReadAsStringAsync();
}
The responseMsg property returned by the request as the response can be parsed as a string and otherwise converted to and validated as xml using an expression such as
XDocument xdoc = XDocument.Parse(responseMsg);
string xmlAsString = xdoc.ToString();

Categories