c# postasync returns unauthorized - c#

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.

Related

ASP.NET Web API post to an external api

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 ?
}

HttpClient sending parameter null

I'm trying to send data to an api with HttpClient but parameter I'm sending keeps received as 0.
What am I doing wrong here? It's my first usage of HttpClient so it's quite possible I mixed things or made some rookie mistake.
Path is correct, I can get results from Postman.
Code I'm using is this;
static async Task GetActivityList()
{
string uri = "/api/ExtraNet/GetActivityList";
HttpClient client = new HttpClient();
int SalesPersonId = 553;
string token = my token value is here;
client.BaseAddress = new Uri("http://localhost:16513/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var postData = "{\"SalesPersonId=\":\""+SalesPersonId+"\"}";
var stringContent = new StringContent( "{\"SalesPersonId=\":\"" + SalesPersonId + "\"}", Encoding.UTF8, "application/json") ;
var content = new StringContent(postData, Encoding.UTF8, "application/json");
var response = await client.PostAsync("http://localhost:16513/api/ExtraNet/GetActivityList", stringContent);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
I managed to send the parameter this way
string uri = "/api/ExtraNet/GetActivityList";
HttpClient client = new HttpClient();
int SalesPersonId = 553;
string token = "";
client.BaseAddress = new Uri("http://localhost:16513/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var stringContent = new FormUrlEncodedContent(new[] {
new KeyValuePair<string,string>("SalesPersonId","553")
});
var response = await client.PostAsync(uri, stringContent);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
Sending the parameters as FormUrlEncodedContent did the trick.

How do I add the profile parameter to the content-type header in C#?

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.

Authorising POST to Vimeo API with C# HttpClient

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);

Trustpilot OAuth Restful API: Unable to PostAsync

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?

Categories

Resources