I am trying to make a POST to the Vimeo API but I am getting 401 Authorization Required.
This is my code for the request (I am just sending the first request that the docs says should return me a ticket ID for uploading).
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://api.vimeo.com");
var byteArray = Encoding.ASCII.GetBytes(accessToken);
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
var form = new FormUrlEncodedContent(new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("type","POST")
});
var response = await client.PostAsync("/me/videos", form);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
I also tried adding access token like this:
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", accessToken);
It always return 401.
What is proper way to add the access token?
This is how header must be:
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
Related
I try to update a field using REST in C#. Using PatchAsync did not work so far, so I'm trying to use PUT instead, but now I need to pass the X-HTTP-METHOD-Override Header and I have no idea how to do this.
I've looked at the available headers for the DefaultRequestHeaders, but I could not find anything.
This is what I have got so far:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(BASEURL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = CreateAuthHeader();
var requestBody = new Dictionary<string, string>
{
{ "price", price.ToString() }
};
var jsonRequest = JsonConvert.SerializeObject(requestBody);
var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json-patch+json");
var response = new HttpResponseMessage();
response = await client.PutAsync($"{APIBASE}/data/ProductAttribute/{attributeId}", content).ConfigureAwait(false);
This should work like normal:
client.DefaultRequestHeaders.Add("X-HTTP-METHOD-Override", "PATCH");
I'm assuming you want PATCH as verb.
I would like to ask if it is possible for a created ASP.NET Web API (written in C#) to post to an external API?
If it is possible, please share sample code that can post to an url with adding headers and receive a callback from the external API.
A simple way to make HTTP-Request out of a .NET-Application is the System.Net.Http.HttpClient (MSDN). An example usage would look something like this:
// Should be a static readonly field/property, wich is only instanciated once
var client = new HttpClient();
var requestData = new Dictionary<string, string>
{
{ "field1", "Some data of the field" },
{ "field2", "Even more data" }
};
var request = new HttpRequestMessage() {
RequestUri = new Uri("https://domain.top/route"),
Method = HttpMethod.Post,
Content = new FormUrlEncodedContent(requestData)
};
request.Headers // Add or modify headers
var response = await client.SendAsync(request);
// To read the response as string
var responseString = await response.Content.ReadAsStringAsync();
// To read the response as json
var responseJson = await response.Content.ReadAsAsync<ResponseObject>();
Essentially you need use an instance of HttpClient to send an HttpRequestMessage to an endpoint.
Here is an example to post some jsonData to someEndPointUrl:
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, someEndPointUrl);
request.Headers.Accept.Clear();
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json");
var response = await client.SendAsync(request, CancellationToken.None);
var str = await response.Content.ReadAsStringAsync();
if (response.StatusCode == HttpStatusCode.OK)
{
// handle your response
}
else
{
// or failed response ?
}
I have the following code. It is returning a 401 Unauthorized although it works perfectly on PostMan.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", string.Format("Bearer {0}", token));
var data1 = new { fName = "Sam", lName = "F" };
var result = await client.PostAsync(url, new StringContent(data1.ToString(), Encoding.UTF8, "application/json"));
var response = result.ToString();
What could be wrong here in the above code?
Start adding headers as they appear in Postman, one-by-one to your request.
One or more of them is what you're missing.
You can also use Fiddler to verify that how you think your request looks like, is how it actually looks like.
you can try this
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var json = JsonConvert.SerializeObject(data1);
var contentData = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url,contentData);
if it is not working, then you have problem with roles. Your API must be have a role authorization too, not just a token.
I'm trying to set the content-type of my HttpClient Post request, and use the profile parameter, but when I change the content type I get an exception thrown:
"The format of value 'application/json; profile={URL HERE}' is
invalid."
For reference, I found this Q&A: Zoopla Sandbox with cURL http header error
X509Certificate2 cert = new X509Certificate2("cert.pfx", "PASSWORD");
WebRequestHandler handler = new WebRequestHandler();
handler.ClientCertificates.Add(cert);
var client = new HttpClient(handler);
client.BaseAddress = new Uri("https://realtime-listings-api.webservices.zpg.co.uk");
var stringContent = new StringContent(propertyData, Encoding.UTF8, "application/json; profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.1/schemas/listing/list.json");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var response = await client.PostAsync("/sandbox/v1/listing/list", stringContent);
return _resultFactory.Create(true, await response.Content.ReadAsStringAsync());
If you create a HttpRequestMessage and use client.SendAsync(), you can add the parameters to request.Content.Headers.ContentType.Parameters
var client = new HttpClient();
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list"))
{
request.Content = new StringContent("propertyData", Encoding.UTF8, "application/json");
request.Content.Headers.ContentType.Parameters.Add(
new NameValueHeaderValue("profile", "http://realtime-listings.webservices.zpg.co.uk/docs/v1.1/schemas/listing/list.json")
);
var response = await client.SendAsync(request);
//Handle response..
}
You don't need to use HttpRequestMessage but you do need to add the profile value as a quoted string via the NameValueHeaderValue parameter:
var content = new StringContent(request.ToJson(), Encoding.UTF8);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("profile", "\"https://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/update.json\""))
httpClient.PostAsync("listing/update", content);
This will get round the FormatException. Otherwise you will run into this dotnet bug.
I am trying to use the Trustpilot API, to post invitations to review products.
I have successfully gone through the authentication step as you can see in the code below, however I am unable to successfully post data to the Trustpilot Invitations API. The PostAsnyc method appears to be stuck with an WaitingForActivation status. I wonder if there is anything you can suggest to help.
Here is my code for this (the API credentials here aren't genuine!):
using (HttpClient httpClient = new HttpClient())
{
string trustPilotAccessTokenUrl = "https://api.trustpilot.com/v1/oauth/oauth-business-users-for-applications/accesstoken";
httpClient.BaseAddress = new Uri(trustPilotAccessTokenUrl);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var authString = "MyApiKey:MyApiSecret";
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Base64Encode(authString));
var stringPayload = "grant_type=password&username=MyUserEmail&password=MyPassword";
var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage httpResponseMessage = httpClient.PostAsync(trustPilotAccessTokenUrl, httpContent).Result;
var accessTokenResponseString = httpResponseMessage.Content.ReadAsStringAsync().Result;
var accessTokenResponseObject = JsonConvert.DeserializeObject<AccessTokenResponse>(accessTokenResponseString);
// Create invitation object
var invitation = new ReviewInvitation
{
ReferenceID = "inv001",
RecipientName = "Jon Doe",
RecipientEmail = "Jon.Doe#comp.com",
Locale = "en-US"
};
var jsonInvitation = JsonConvert.SerializeObject(invitation);
var client = new HttpClient();
client.DefaultRequestHeaders.Add("token", accessTokenResponseObject.AccessToken);
var invitationsUri = new Uri("https://invitations-api.trustpilot.com/v1/private/business-units/{MyBusinessID}/invitations");
// This here as a status of WaitingForActivation!
var a = client.PostAsync(invitationsUri, new StringContent(jsonInvitation)).ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode());
}
This is how I solved the issue:
// Serialize our concrete class into a JSON String
var jsonInvitation = JsonConvert.SerializeObject(invitationObject);
// Wrap our JSON inside a StringContent which then can be used by the HttpClient class
var stringContent = new StringContent(jsonInvitation);
// Get the access token
var token = GetAccessToken().AccessToken;
// Create a Uri
var postUri = new Uri("https://invitations-api.trustpilot.com/v1/private/business-units/{BusinessUnitID}/invitations");
// Set up the request
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, postUri);
request.Content = stringContent;
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
request.Content.Headers.Add("token", token);
// Set up the HttpClient
var httpClient = new HttpClient();
//httpClient.DefaultRequestHeaders.Accept.Clear();
//httpClient.BaseAddress = postUri;
//httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
//httpClient.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en-US"));
var task = httpClient.SendAsync(request);
task.Wait();
This question here on SO was helpful:
How do you set the Content-Type header for an HttpClient request?