How to call API in asp.net MVC5 - c#

I have asp.net mvc5 project that I want to call another API using JSON,
and I want to call that API from my Controller action because I need to do some hashing in there,
It's my first time doing this, and I need to send the request in JSON and also get responses in JSON all of that using the controller action.

If your method is POST :
string uri = "yourdomain/api/controller/method;
var client = new HttpClient();
var values = new Dictionary<string, string>()
{
{"username", SecurityHelper.EncryptQueryString(username)},
{"password", SecurityHelper.EncryptQueryString(password)},
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync(uri, content);
response.EnsureSuccessStatusCode();
If your method is GET :
string url = "domain/api/controller/method?parameter1=param";
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var jsonResponse = response.Content.ReadAsStringAsync().Result;
bool data = JsonConvert.DeserializeObject<bool>(jsonResponse);
return data;
}
}

var client = new HttpClient();
var payload = #"{
'CPU': 'Intel',
'PSU': '500W',
'Drives': [
'DVD read/writer',
'500 gigabyte hard drive',
'200 gigabype hard drive'
]
}";
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var url = {APIEndpoint};
var result = await client.PostAsync(url, content);
Response parsing using JSON.NET:
JObject joResponse = JObject.Parse(result);

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.

How to send json request body data in POST request using C#

I am New in C#.
I want to send JSON request body in POST request using C#.
I want To get results from Rest URL but it's showing me status code 500.
How can I format the request body so that I able to get results from the rest URL?
My Request body in JSON -->
{"filter":{"labtestName":[{"labtestName":"Ada"}]}}
code that I tried
string data1 = "{\filter\":{\"labtestName\":[{\"labtestName\":\"Ada\"}]}}";
var RestURL = "https://nort.co.net/v1api/LabTest/Hurlabtest";
HttpClient client = new HttpClient();
string jsonData = JsonConvert.SerializeObject(data1);
client.BaseAddress = new Uri(RestURL);
StringContent content1 = new StringContent(jsonData, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("apptoken", "72f303a7-f1f0-45a0-ad2b-e6db29328b1a");
client.DefaultRequestHeaders.Add("usertoken", "cZJqFMitFdVz5MOvRLT7baVTJa+yZffc5eVoU91OqkMYl6//cQmgIVkHOyRZ7rWTXi66WV4tMEuj+0oHIyPS6hBvPUY5/RJ7oWnTr4LuzlKU1H7Cp68za57O9AatAJJHiVPowlXwoPUohqe8Ad2u0A==");
HttpResponseMessage response = await client.PostAsync(RestURL, content1);
var result = await response.Content.ReadAsStringAsync();
var responseData = JsonConvert.DeserializeObject<LabtestResponseData>(result);
You are sending the wrong data to the method,
I have corrected it, you can refer to the below code.
myData string is already a JSON string so there is no need to serialize it again.
string myData = "{\"filter\": {\"labtestName\": [{\"labtestName\": \"Ada\"}]}}";
//string data1 = "{\filter\": {\"labtestName\": [{\"labtestName\": \"Ada\"}]}}";
var RestURL = "https://tcdevapi.iworktech.net/v1api/LabTest/HSCLabTests";
HttpClient client = new HttpClient();
//string jsonData = JsonConvert.SerializeObject(myData);
client.BaseAddress = new Uri(RestURL);
StringContent content1 = new StringContent(myData, Encoding.UTF8, "application/json");

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;

Troubleshooting HTTPClient asynchronous POST and reading results

I have a problem post string to form and read. Problem is they get away but need to do so sophisticated and it was very fast. Absolutely perfect multithreaded or asynchronous. Thank you very for your help.
This is my code.
private static void AsyncDown()
{
const string url = "http://whois.sk-nic.sk/index.jsp";
const string req = "PREM-0001";
var client = new HttpClient();
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("text", "PREM-0001")
};
FormUrlEncodedContent content = new FormUrlEncodedContent(pairs);
HttpResponseMessage response = client.PostAsync("http://whois.sk-nic.sk/index.jsp", content).Result;
if (response.IsSuccessStatusCode)
{
HttpContent stream = response.Content;
Task<string> data = stream.ReadAsStringAsync();
}
}
Taking a rough stab in the dark at what your problem is, I'd guess that you're having trouble reading the response of your call.
When the content is POSTed to the server,
HttpResponseMessage response
= client.PostAsync("http://whois.sk-nic.sk/index.jsp", content).Result;
if (response.IsSuccessStatusCode)
{
HttpContent stream = response.Content;
Task<string> data = stream.ReadAsStringAsync();
}
It does so asynchronously, so the code will continue execution even though the result is not (most likely) available yet. Checking response.IsSuccessStatusCode will thus not give you the behavior you're expecting.
Change your calls to look like this by adding the await keyword:
HttpResponseMessage response
= await client.PostAsync("http://whois.sk-nic.sk/index.jsp", content);
Then, change the reading of the stream to use await as well:
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
}
EDIT: got some await objects mixed up and have corrected the code listing.
edit 2: here is the complete LINQPad script that I used to successfully download an HTML page from the given URL.
var client = new HttpClient();
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("text", "PREM-0001")
};
FormUrlEncodedContent content = new FormUrlEncodedContent(pairs);
HttpResponseMessage response = await client.PostAsync("http://whois.sk-nic.sk/index.jsp", content);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
//data.Dump(); //uncomment previous if using LINQPad
}
Maybe the site has changed since last post but now the request parameter name is whois not text. If this was the case a year ago too that's why it didn't work.
Today site responds to get too, i.e. http://whois.sk-nic.sk/index.jsp?whois=PREM-0001
Full code with get:
private async Task<string> Get(string code)
{
using (var client = new HttpClient())
{
var requestUri = String.Format("http://whois.sk-nic.sk/index.jsp?whois={0}", code);
var data = await client.GetStringAsync(requestUri);
return data;
}
}
Full code with post:
private async Task<string> Post()
{
using (var client = new HttpClient())
{
var postData = new KeyValuePair<string, string>[]
{
new KeyValuePair<string, string>("whois", "PREM-0001"),
};
var content = new FormUrlEncodedContent(postData);
var response = await client.PostAsync("http://whois.sk-nic.sk/index.jsp", content);
if (!response.IsSuccessStatusCode)
{
var message = String.Format("Server returned HTTP error {0}: {1}.", (int)response.StatusCode, response.ReasonPhrase);
throw new InvalidOperationException(message);
}
var data = await response.Content.ReadAsStringAsync();
return data;
}
}
Or a parser could be used because I guess extracting the returned values is the final goal:
private void HtmlAgilityPack(string code)
{
var requestUri = String.Format("http://whois.sk-nic.sk/index.jsp?whois={0}", code);
var request = new HtmlWeb();
var htmlDocument = request.Load(requestUri);
var name = htmlDocument.DocumentNode.SelectSingleNode("/html/body/table[1]/tr[5]/td/table/tr[2]/td[2]").InnerText.Trim();
var organizations = htmlDocument.DocumentNode.SelectSingleNode("/html/body/table[1]/tr[5]/td/table/tr[3]/td[2]").InnerText.Trim();
}

Categories