I wrote a function which consumes Web API. This function works great for GET requests. However, I need to get some other resources from API which, according to API provider's docs, requires POST method. So I've simply changed HttpMethod from Get to HttpMethod.Post. When I call the API then I get Error 400 Bad Request.
CallAPI
private static async Task<T> CallAPI<T>(string endpoint, string accessToken)
{
var request = new HttpRequestMessage(HttpMethod.Post,
new Uri(ApiUri, endpoint));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var _httpClient = new HttpClient();
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var responseStream = await response.Content.ReadAsStreamAsync();
var responseObject = await JsonSerializer.DeserializeAsync<T>(responseStream);
return responseObject;
}
I call this API:
var result = await CallAPI<SomeDataModel>("cars/locations", accessToken);
Don't know where is a problem. It works great for GET as I said. Moreover, I don't understand why there's a need to use POST instead of GETto get data. I think it's against REST best-practices. According to provider's API docs, I don't need to attach any parameters to POST request, it's just raw endpoint. Anyways, I need to use POST here to get data.
I have two web APIs applications developed in .Net core. I need to import Json data from the second application to the first. However,I have a security issue. I need to secure the access to the external API. How should I securely manage the connection between these two APIs.
For example, I need to secure the access to the URL in the code bellow => securely access to the covid API without another authentication.
PS: I'm using JWT token authentication in both applications
Best regards.
using (var client = new HttpClient())
{
string url = string.Format("https://covid19.mathdro.id/api");
var response = client.GetAsync(url).Result;
string responseAsString = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<CovidResult>(responseAsString);
}
If both APIs are protected by the same accessToken, then you can read the authorization header from the first request and pass it to the second request.
Something like this to read the header:
var authHeader = context.Request.Headers.Get("Authorization");
You should end up with authHeader equal to "Bearer ey...(a bunch of base64)"
Then add the auth header to the client:
var request = new HttpRequestMessage() {
RequestUri = new Uri("http://https://covid19.mathdro.id/api"),
Method = HttpMethod.Get,
};
...
request.Headers.Authorization.Add(new AuthenticationHeaderValue(authHeader));
var task = client.SendAsync(request)
I'm using HttpClient in .Net core 3.1. Most of my requests follow a similar pattern regardless of the HTTP method used:
build URL
build (optional) JSON payload
send request
await response
check status code
parse (optional) JSON response
so I've built a wrapper function that does all these things, and it takes the HTTP method as a parameter. However, when it comes to the "send request" step, I need to use a switch statement to invoke the appropriate method on HttpClient to invoke.
I'm sure that under the skin, get GetAsync() PostAsync() etc. are calling the same underlying function and passing the Http method as a parameter. but I can't see any way of calling it like this from the outside. It seems a strange omission as in my experience most HTTP libraries work that way.
Hope this will help you.
// For JsonConvert use Newtonsoft.Json
string url = "YourURL";
string body = JsonConvert.SerializeObject(BodyModel);
string headerParameter = "ASD123456789";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // Content-Type of request, it can be application/xml to other
client.DefaultRequestHeaders.Add("Device", headerParameter ); // first is name, second one is value
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url) // there you can have Get, Post, Put, Delete and etc. And every request needs to be configured by its settings
{
Content = new StringContent(body, Encoding.UTF8, "application/json")
};
HttpResponseMessage response = await client.SendAsync(request);
if ((int)response.StatusCode == 200)
{
string responseString = await response.Content.ReadAsStringAsync();
ResponseModel responseModel = JsonConvert.DeserializeObject<ResponseModel>(responseString);
}
I am beginner and creating winform application. In which i have to use API for Simple CRUD operation. My client had shared API with me and asked to send data in form of JSON.
API : http://blabla.com/blabla/api/login-valida
KEY : "HelloWorld"
Value : { "email": "user#gmail.com","password": "123456","time": "2015-09-22 10:15:20"}
Response : Login_id
How can i convert data to JSON, call API using POST method and get response?
EDIT
Somewhere on stackoverflow i found this solution
public static void POST(string url, string jsonContent)
{
url="blabla.com/api/blala" + url;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(baseURL);
request.Method = "POST";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(jsonContent);
request.ContentLength = byteArray.Length;
request.ContentType = #"application/json";
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
long length = 0;
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
length = response.ContentLength;
}
}
catch
{
throw;
}
}
//on my login button click
private void btnLogin_Click(object sender, EventArgs e)
{
CallAPI.POST("login-validate", "{ \"email\":" + txtUserName.Text + " ,\"password\":" + txtPassword.Text + ",\"time\": " + DateTime.Now.ToString("yyyy-MM-dd h:mm tt") + "}");
}
I got exception that says "The remote server returned an error: (404) Not Found."
You can take a look at the following docs tutorial:
Call a Web API From a .NET Client
But as an answer, here I will share a quick and short a step by step guide about how to call and consume web API in Windows forms:
Install Package - Install the Microsoft.AspNet.WebApi.Client NuGet package (Web API Client Libraries).
Open Tools menu → NuGet Package Manager → Package Manager Console → In the Package Manager Console window, type the following command:
Install-Package Microsoft.AspNet.WebApi.Client
You can install package by right click on project and choosing Manage NuGet Packages as well.
Set up HttpClient - Create an instance of HttpClient and set up its BaseAddress and DefaultRequestHeaders. For example:
// In the class
static HttpClient client = new HttpClient();
// Put the following code where you want to initialize the class
// It can be the static constructor or a one-time initializer
client.BaseAddress = new Uri("http://localhost:4354/api/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
Send Request - To send the requests, you can use the following methods of the HttpClient:
GET: GetAsync, GetStringAsync, GetByteArrayAsync, GetStreamAsync
POST: PostAsync, PostAsJsonAsync, PostAsXmlAsync
PUT: PutAsync, PutAsJsonAsync, PutAsXmlAsync
DELETE: DeleteAsync
Another HTTP method: Send
Note: To set the URL of the request for the methods, keep in mind, since you have specified the base URL when you defined the client, then here for these methods, just pass path, route values and query strings, for example:
// Assuming http://localhost:4354/api/ as BaseAddress
var response = await client.GetAsync("products");
or
// Assuming http://localhost:4354/api/ as BaseAddress
var product = new Product() { Name = "P1", Price = 100, Category = "C1" };
var response = await client.PostAsJsonAsync("products", product);
Get the Response
To get the response, if you have used methods like GetStringAsync, then you have the response as string and it's enough to parse the response. If the response is a Json content which you know, you can easily use JsonConvert class of Newtonsoft.Json package to parse it. For example:
// Assuming http://localhost:4354/api/ as BaseAddress
var response = await client.GetStringAsync("product");
var data = JsonConvert.DeserializeObject<List<Product>>(response);
this.productBindingSource.DataSource = data;
If you have used methods like GetAsync or PostAsJsonAsync and you have an HttpResponseMessage then you can use ReadAsAsync, ReadAsByteArrayAsync, ReadAsStreamAsync, `ReadAsStringAsync, for example:
// Assuming http://localhost:4354/api/ as BaseAddress
var response = await client.GetAsync("products");
var data = await response.Content.ReadAsAsync<IEnumerable<Product>>();
this.productBindingSource.DataSource = data;
Performance Tip
HttpClient is a type that is meant to be created once and then shared. So don't try to put it in a using block every time that you want to use it. Instead, create an instance of the class and share it through a static member. To read more about this, take a look at Improper Instantiation antipattern
Design Tip
Try to avoid mixing the Web API related code with your application logic. For example let's say you have a product Web API service. Then to use it, first define an IProductServieClient interface, then as an implementation put all the WEB API logic inside the ProductWebAPIClientService which you implement to contain codes to interact with WEB API. Your application should rely on IProductServieClient. (SOLID Principles, Dependency Inversion).
Just use the following library.
https://www.nuget.org/packages/RestSharp
GitHub Project: https://github.com/restsharp/RestSharp
Sample Code::
public Customer GetCustomerDetailsByCustomerId(int id)
{
var client = new RestClient("http://localhost:3000/Api/GetCustomerDetailsByCustomerId/" + id);
var request = new RestRequest(Method.GET);
request.AddHeader("X-Token-Key", "dsds-sdsdsds-swrwerfd-dfdfd");
IRestResponse response = client.Execute(request);
var content = response.Content; // raw content as string
dynamic json = JsonConvert.DeserializeObject(content);
JObject customerObjJson = json.CustomerObj;
var customerObj = customerObjJson.ToObject<Customer>();
return customerObj;
}
Use Json.Net to convert data into JSON
Use WebClient to POST data
Use This code:
var client = new HttpClient();
client.BaseAddress = new Uri("http://www.mywebsite.com");
var request = new HttpRequestMessage(HttpMethod.Post, "/path/to/post/to");
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("site", "http://www.google.com"));
keyValues.Add(new KeyValuePair<string, string>("content", "This is some content"));
request.Content = new FormUrlEncodedContent(keyValues);
var response = await client.SendAsync(request);
Here is another example using an online REST service (https://northwind.vercel.app) which allows interaction with Northwind API.
This example uses HttpClient and JsonConvert to get or post data. Here is a very quick example:
Install Newtonsoft.Json nuget package. And add the following using statements to your form:
using System.Net.Http;
using Newtonsoft.Json
Define an instance of the HttpClient, at class level:
private static HttpClient client = new HttpClient();
To send a GET request, for example getting list of all data:
var url = "https://northwind.vercel.app/api/categories";
var response = await client.GetAsync(url);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var content = await response.Content.ReadAsStringAsync();
var categories = JsonConvert.DeserializeObject<List<Category>>(content);
dataGridView1.DataSource = categories;
}
You can also use other overloads of Get, like GetStringAsync, GetStreamAsync, and etc. But GetAsync is a more generic method allowing you to get the status code as well.
To send a POST request, for example posting a new data:
var url = "https://northwind.vercel.app/api/categories";
var data = new Category() { Name = "Lorem", Description = "Ipsum" };
var jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(data);
var requestContent = new StringContent(jsonData, Encoding.Unicode, "application/json");
var response = await client.PostAsync(url, requestContent);
if (response.StatusCode == System.Net.HttpStatusCode.Created)
{
var content = await response.Content.ReadAsStringAsync();
var createdCategory = JsonConvert.DeserializeObject<Category>(content);
MessageBox.Show(createdCategory.Id.ToString())
}
To learn more and see some best practices or see an example without JsonConvert, see my other post.
I'm trying to access an API, but all the documentation is in PHP and I'm not very familiar with PHP. I am having trouble authenticating to the API. The documentation is here.
Here is what I have so far
var webAddress = "https://xboxapi.com/v2/latest-xbox360-games";
var httpResponse = (new HttpClient().GetAsync(webAddress)).Result;
httpResponse.EnsureSuccessStatusCode();
var jsonResponse = httpResponse.Content.ReadAsStringAsync().Result;
I'm just not sure how to add the authentication header that they are using in PHP.
Any help would be appreciated.
To add a custom header (in this case X-AUTH), you need to send a custom HttpRequestMessage. For example:
var webAddress = "https://xboxapi.com/v2/latest-xbox360-games";
HttpClient client = new HttpClient();
HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Get, webAddress);
msg.Headers.Add('X-AUTH', 'your-auth-key-here');
HttpResponseMessage response = await client.SendAsync(msg);