Hi guys this is my first time using web api and I hope you can point me in the right direction. How do I add the api key in request header using web api?
I tried to check google but i'm not sure if I'm looking at the right guide.
This is what I found > How to add and get Header values in WebApi
My goal is to make a GET request and add the API key in the request headers.
You always have key-value pair in header of any API request. For example here you have the header with key as "api_key" and value as "1234". You can add this in your Http request by the way given below.
HttpClient httpClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage();
request.RequestUri = new Uri("Your_get_URI");
request.Method = HttpMethod.Get;
request.Headers.Add("api_key", "1234");
HttpResponseMessage response = await httpClient.SendAsync(request);
var responseString = await response.Content.ReadAsStringAsync();
var statusCode = response.StatusCode;
If you are using DI you could easily inject a configured HttpClient by doing a little setup in Startup.cs
The following is a working example of configuring a HttpClient for use with Microsoft's App Insights api. Of course you will have to change your header as needed.
public void ConfigureServices(IServiceCollection services)
{
//Somewhere in the ConfigureSerices method.
services.AddHttpClient("APPINSIGHTS_CLIENT", c =>
{
c.BaseAddress = "<API_URL_HERE>";
c.DefaultRequestHeaders.Add("x-api-key", clientKey));
}
}
Now if you inject IHttpClientFactory for use downstream, and call it will be configured and ready to be used without any fuss.
HttpClient client = factory.CreateClient("APPINSIGHTS_CLIENT");
Try this, I hope this will work for you.
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("API URL");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Authorization = new
System.Net.Http.Headers.AuthenticationHeaderValue("Pass your token value or API key");
HttpResponseMessage response = await httpClient.GetAsync(endpoint);
if (response.StatusCode == HttpStatusCode.OK)
{
string result = await response.Content.ReadAsStringAsync();
if (string.IsNullOrEmpty(result))
return "Success";
else
return result;
}
else if (response.StatusCode == HttpStatusCode.Unauthorized)
{
throw new UnauthorizedAccessException();
}
else
{
throw new Exception(await response.Content.ReadAsStringAsync());
}
}
Related
I'm trying to use the Reddit API (https://github.com/reddit-archive/reddit/wiki/OAuth2) in my ASP.NET Core MVC app, and to obtain a token I have to make a POST to a URI with HTTP Basic Authorization (username and password being a client id and secret). Currently I use this code:
public async Task<HttpResponseMessage> HttpPost(string uri, string value)
{
HttpClient httpClient = new HttpClient();
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(uri, new StringContent(value));
return httpResponseMessage;
}
However, this doesn't use the authorization. How can I add authorization? I tried looking at the documentation for HttpClient.PostAsync and HttpContent, but I don't see anything relevant.
You will need to create a base64 encoded string with format: username:password. Then add it to Authorization header for Http Request.
Example:
using (var client = new HttpClient { BaseAddress = new Uri("https://baseUrl") })
{
var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes("username:password"));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
var response = await client.PostAsync(requestUri, new StringContent(value));
}
I am trying to call the REST API exposed from IBM TM1 Cognos. Using the HttpWebRequest object. Getting the 401 when i tried to pass Authorization header with base64(user:password:namespaceId).
using (var client = new HttpClient())
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes("username:password:camnamespace");
var encodeData= System.Convert.ToBase64String(plainTextBytes);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", "CAMNamespace "+ encodeData);
//GET Method
HttpResponseMessage response = await client.GetAsync("http://serveraddress/api/v1/Cubes");
if (response.IsSuccessStatusCode)
{
var det = await response.Content.ReadAsStringAsync();
}
else
{
Console.WriteLine("Internal server Error");
}
}
I think you need something like in payton: verify=False to trust the certificate of response.
I am using oAuth to authenticate my app. I managed to get a code, access_token and refresh_token. So the next step would be trying to get info about the current user.
public async void GetCurrentUser()
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken);
var response = await client.GetAsync("https://oauth.reddit.com/api/v1/me");
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
}
}
}
This is the method I am using to do that. However the response is always an 403 (Forbidden) error code. Any idea what could be wrong? The access_token is what I got when I made a request to https://oauth.reddit.com/api/v1/access_token
I think the token is correct because when I create the same request with Fiddler it works.
ANSWER:
Fixed it by adding a custom user-agent
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, _endpointUri + "me");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
request.Headers.Add("User-Agent", Uri.EscapeDataString("android:com.arnvanhoutte.redder:v1.2.3 (by /u/nerdiator)"));
var response = await client.SendAsync(request);
I'm implementing an API made by other colleagues with Apiary.io, in a Windows Store app project.
They show this example of a method I have to implement:
var baseAddress = new Uri("https://private-a8014-xxxxxx.apiary-mock.com/");
using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
{
using (var response = await httpClient.GetAsync("user/list{?organizationId}"))
{
string responseData = await response.Content.ReadAsStringAsync();
}
}
In this and some other methods, I need to have a header with a token that I get before.
Here's an image of Postman (chrome extension) with the header I'm talking about:
How do I add that Authorization header to the request?
A later answer, but because no one gave this solution...
If you do not want to set the header on the HttpClient instance by adding it to the DefaultRequestHeaders, you could set headers per request.
But you will be obliged to use the SendAsync() method.
This is the right solution if you want to reuse the HttpClient -- which is a good practice for
performance and port exhaustion problems
doing something thread-safe
not sending the same headers every time
Use it like this:
using (var requestMessage =
new HttpRequestMessage(HttpMethod.Get, "https://your.site.com"))
{
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", your_token);
await httpClient.SendAsync(requestMessage);
}
When using GetAsync with the HttpClient you can add the authorization headers like so:
httpClient.DefaultRequestHeaders.Authorization
= new AuthenticationHeaderValue("Bearer", "Your Oauth token");
This does add the authorization header for the lifetime of the HttpClient so is useful if you are hitting one site where the authorization header doesn't change.
Here is an detailed SO answer
The accepted answer works but can get complicated when you want to try adding Accept headers. This is what I ended up with. It seems simpler to me, so I think I'll stick with it in the future:
client.DefaultRequestHeaders.Add("Accept", "application/*+xml;version=5.1");
client.DefaultRequestHeaders.Add("Authorization", "Basic " + authstring);
Sometimes, you only need this code.
httpClient.DefaultRequestHeaders.Add("token", token);
Following the greenhoorn's answer, you can use "Extensions" like this:
public static class HttpClientExtensions
{
public static HttpClient AddTokenToHeader(this HttpClient cl, string token)
{
//int timeoutSec = 90;
//cl.Timeout = new TimeSpan(0, 0, timeoutSec);
string contentType = "application/json";
cl.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType));
cl.DefaultRequestHeaders.Add("Authorization", String.Format("Bearer {0}", token));
var userAgent = "d-fens HttpClient";
cl.DefaultRequestHeaders.Add("User-Agent", userAgent);
return cl;
}
}
And use:
string _tokenUpdated = "TOKEN";
HttpClient _client;
_client.AddTokenToHeader(_tokenUpdated).GetAsync("/api/values")
These days, if you are using MS Dependency Injection, it's highly recomended to plug in the IHttpClientFactory:
builder.Services.AddHttpClient("GitHub", httpClient =>
{
httpClient.BaseAddress = new Uri("https://api.github.com/");
// using Microsoft.Net.Http.Headers;
// The GitHub API requires two headers.
httpClient.DefaultRequestHeaders.Add(
HeaderNames.Accept, "application/vnd.github.v3+json");
httpClient.DefaultRequestHeaders.Add(
HeaderNames.UserAgent, "HttpRequestsSample");
});
var httpClient = _httpClientFactory.CreateClient("GitHub");
This way you avoid adding default request headers to a globally shared httpclient and moreover don't have to deal with manual creation of the HttpRequestMessage.
Source:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-6.0#consumption-patterns
I use codes below to send POST request to a server:
string url = "http://myserver/method?param1=1¶m2=2"
HttpClientHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
HttpResponseMessage response = await httpClient.SendAsync(request);
I don't have access to the server to debug but I want to know, is this request sent as POST or GET?
If it is GET, How can I change my code to send param1 & param2 as POST data (not in the URL)?
A cleaner alternative would be to use a Dictionary to handle parameters. They are key-value pairs after all.
private static readonly HttpClient httpclient;
static MyClassName()
{
// HttpClient is intended to be instantiated once and re-used throughout the life of an application.
// Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads.
// This will result in SocketException errors.
// https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netframework-4.7.1
httpclient = new HttpClient();
}
var url = "http://myserver/method";
var parameters = new Dictionary<string, string> { { "param1", "1" }, { "param2", "2" } };
var encodedContent = new FormUrlEncodedContent (parameters);
var response = await httpclient.PostAsync (url, encodedContent).ConfigureAwait (false);
if (response.StatusCode == HttpStatusCode.OK) {
// Do something with response. Example get content:
// var responseContent = await response.Content.ReadAsStringAsync ().ConfigureAwait (false);
}
Also dont forget to Dispose() httpclient, if you dont use the keyword using
As stated in the Remarks section of the HttpClient class in the Microsoft docs, HttpClient should be instantiated once and re-used.
Edit:
You may want to look into response.EnsureSuccessStatusCode(); instead of if (response.StatusCode == HttpStatusCode.OK).
You may want to keep your httpclient and dont Dispose() it. See: Do HttpClient and HttpClientHandler have to be disposed?
Edit:
Do not worry about using .ConfigureAwait(false) in .NET Core. For more details look at https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html
This is how I use it for DI:
using HttpClient httpClient = clientFactory.CreateClient("name set in builder host");
// httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"Token {token}");
HttpResponseMessage? res = await httpClient!.PostAsync(url, content);
try
{
res.EnsureSuccessStatusCode();
return res;
}
catch (Exception)
{
// Add error handling
}
content is:
List<KeyValuePair<string, string>> values = new()
{
new KeyValuePair<string, string>("data", "value")
};
FormUrlEncodedContent requestContent = new(values);
and clientFactory is the interface:
IHttpClientFactory
msdn interface
As Ben said, you are POSTing your request ( HttpMethod.Post specified in your code )
The querystring (get) parameters included in your url probably will not do anything.
Try this:
string url = "http://myserver/method";
string content = "param1=1¶m2=2";
HttpClientHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
HttpResponseMessage response = await httpClient.SendAsync(request,content);
HTH,
bovako