API request WaitingForActivation "Not yet computed" error via asp.net - c#

this is my code via asp.net web form:
public string GetAccessToken()
{
ServicePointManager.Expect100Continue=true;
string accessToken = "";
System.Net.ServicePointManager.SecurityProtocol=System.Net.SecurityProtocolType.Tls12;
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en_US"));
var clientId = "<"+PAYPAL_CLIENT_ID+">";
var clientSecret = "<"+PAYPAL_SECRET_KEY+">";
var bytes = Encoding.UTF8.GetBytes(clientId+":"+clientSecret);
client.DefaultRequestHeaders.Authorization=new AuthenticationHeaderValue("Basic", Convert.ToBase64String(bytes));
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
var responseMessage = client.PostAsync("https://api.sandbox.paypal.com/v1/oauth2/token", new FormUrlEncodedContent(keyValues));
accessToken= responseMessage.Status.ToString();
}
return accessToken;
}
But I get this error:
Id = 9, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}" in AccessToken

client.PostAsync is an asynchronous method that returns a Task object. You either need to await it (this is the preferred approach), but that would require a change to the signature of the GetAccessToken() function (and probably to the upstream code) or simply do the following:
var responseTask = client.PostAsync("https://api.sandbox.paypal.com/v1/oauth2/token", new FormUrlEncodedContent(keyValues));
responseTask.Wait();
var responseMessage = responseTask.Result;

Related

Postman form-data: How to program it inside a HttpRequestMessage?

I am doing a request through postman to a specific url but I set the form-data type in order to get data to the site like this:
Now I want to program this request inside C# but everything I tried so far is returning a 400 Bad Request response. This is what I tried:
public async Task<CheckAccessTokenModel> CheckAccessTokenAsync(string accessToken)
{
string uriString = "someurl";
var uri = new Uri(uriString);
try
{
using(var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = uri
};
var ClientId = ConfigurationAccessor.Configuration["WebCredentials:ClientId"];
var Secret = ConfigurationAccessor.Configuration["WebCredentials:Secret"];
var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{ClientId}:{Secret}"));
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(new StringContent("token"), accessToken);
request.Content = content;
var response = await httpClient.SendAsync(request);
var checkTokenResponseData = await response.Content.ReadAsStringAsync();
//return new CheckAccessTokenModel { Active = true, Exp = 1647431224233 };
return JsonConvert.DeserializeObject<CheckAccessTokenModel>(checkTokenResponseData);
}
}
catch
{
return null;
}
}
I am doing it with the MultipartFormDataContent Object as suggested by many others here but it still won't work.
What can be the problem here?
EDIT: Wrong picture replaced
You can simply
request.Content = new StringContent($"token={accessToken}");
With form data I think it's something like this:
var data = new Dictionary<string, string>
{
{"token", acccessToken}
};
using var content = new FormUrlEncodedContent(data);
request.Content = content;

Authorizing an Azure REST API Request

I am trying to write a local console application which will swap an Azure Web App slot using the Azure REST API. Using the following code I get a 401 (Unauthorized) response:
public async Task Swap(string subscription, string resourceGroup, string site, string slot)
{
var client = new HttpClient();
var url =
$"https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{site}/applySlotConfig?api-version=2016-08-01";
var data = new {preserveVnet = true, targetSlot = slot};
var message = new HttpRequestMessage
{
RequestUri = new Uri(url),
Method = HttpMethod.Post,
Content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")
};
var response = await client.SendAsync(message);
Console.WriteLine(response.StatusCode);
}
I know I need to put in some kind of credentials but what I have found seems to apply to apps using Azure AD for authentication. This will be a publicly accessible web app with anonymous authentication.
Generally speaking you need to attach a Authorization header to the request with the Auth token. There are numerous ways of getting it, see this link or this.
This is how I managed to do it (using the provided links):
private async Task<string> GetAccessToken(string tenantName, string clientId, string clientSecret)
{
var authString = "https://login.microsoftonline.com/" + tenantName;
var resourceUrl = "https://management.azure.com/";
var authenticationContext = new AuthenticationContext(authString, false);
var clientCred = new ClientCredential(clientId, clientSecret);
var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceUrl, clientCred);
var token = authenticationResult.AccessToken;
return token;
}
And then in my previous method:
public async Task Swap(string subscription, string resourceGroup, string site, string slot)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await GetAccessToken("XXX", "XXX", "XXX"));
var url =
$"https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{site}/applySlotConfig?api-version=2016-08-01";
var data = new {preserveVnet = true, targetSlot = slot};
var message = new HttpRequestMessage
{
RequestUri = new Uri(url),
Method = HttpMethod.Post,
Content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")
};
var response = await client.SendAsync(message);
Console.WriteLine(response.StatusCode);
}

Can't authenticate correctly with headers (HttpClient)

I've checking many forums but I can't make it work. I'm trying to authenticate with headers to an url that will return a JSON string if authentication were successful. In Postman I simply used Get method with username and password in header to get the JSON data. What changes do I need to make my following C# code achieve same thing? I think I even failed to add username and password into headers.
public async Task<string> LogMeIn(string username, string password)
{
var client = new HttpClient {
BaseAddress = new Uri("http://x.com")
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new FormUrlEncodedContent(new[] {
new KeyValuePair<string,string>("grant_type","password"),
new KeyValuePair<string,string>("Username ", username),
new KeyValuePair<string,string>("Password", password)
});
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await client.PostAsync("/login", content); //should it be GetAsync?
var jsonResp = await response.Content.ReadAsStringAsync();
var jsonResult = JsonConvert.DeserializeObject<JsonResult>(jsonResp); //JsonResult = class for json
return jsonResult.token;
}
}

Twilio REST Api call bad request

I've implemented Twilio REST API with C# successfully earlier. However, all of a sudden the API calls that are made keep getting 400 - BAD REQUEST.
The response body doesn't contain any specific error either...
I'll say it again, it worked for a week or two and all of sudden it returns BAD REQUEST.
The code is exact the following below.
public async Task SendSmsAsync(string number, string message)
{
var accountSid = _configuration["Authentication:Twilio:AccountSID"];
var authToken = _configuration["Authentication:Twilio:AuthToken"];
var twilioNumber = _configuration["Authentication:Twilio:Number"];
var credentials = new NetworkCredential(accountSid, authToken);
var handler = new HttpClientHandler { Credentials = credentials };
using (var client = new HttpClient(handler))
{
var url = $"https://api.twilio.com/2010-04-01/Accounts/{ accountSid }/Messages";
var body = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("To", number),
new KeyValuePair<string, string>("From", twilioNumber),
new KeyValuePair<string, string>("Body", message),
};
var content = new FormUrlEncodedContent(body);
content.Headers.ContentType.CharSet = "UTF-8";
var response = await client.PostAsync(url, content);
if (response.IsSuccessStatusCode)
{
//Uri success = response.Headers.Location;
}
}
}

Getting error while posting login info on ASP.NET WEB API call

I am getting this exception while trying to do a post call on a ASP.NET Web API. I am calling this from a Windows Universal App:
Type
'<>f__AnonymousType0`3[System.String,System.String,System.String]'
cannot be serialized. Consider marking it with the
DataContractAttribute attribute.
Here is my code:
var loginData = new { grant_type = "password", username = name, password = pass };
var queryString = "grant_type = password, username = " + name + ", password = " + pass;
HttpClient httpClient = new HttpClient();
try
{
string resourceAddress = "http://localhost:24721/Token";
//int age = Convert.ToInt32(this.Agetxt.Text);
//if (age > 120 || age < 0)
//{
// throw new Exception("Age must be between 0 and 120");
//}
string postBody = Serialize(loginData);
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage wcfResponse = await httpClient.PostAsync(resourceAddress,
new StringContent(queryString, Encoding.UTF8));
}
Best guess is, you're getting that error because the serializer you're using doesn't support anonymous types. I would recommend trying to use Json.Net, which handles them nicely. I believe you can include it from NuGet.
If you reference the library in your project then you could modify your code like so:
var loginData = new { grant_type = "password", username = name, password = pass };
HttpClient httpClient = new HttpClient();
try
{
string resourceAddress = "http://localhost:24721/Token";
string postBody = Newtonsoft.Json.JsonConvert.SerializeObjectloginData);
var content = new StringContent(postBody, Encoding.UTF8, "application/json");
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage wcfResponse = await httpClient.PostAsync(resourceAddress, content);
}
I found the solution. i updated the post data as key value pair and it worked.
using (var client = new HttpClient())
{
string resourceAddress = "http://localhost:24721/Token";
var requestParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", name),
new KeyValuePair<string, string>("password", pass)
};
var requestParamsFormUrlEncoded = new FormUrlEncodedContent(requestParams);
var tokenServiceResponse = await client.PostAsync(resourceAddress, requestParamsFormUrlEncoded);
var responseString = await tokenServiceResponse.Content.ReadAsStringAsync();
var responseCode = tokenServiceResponse.StatusCode;
var responseMsg = new HttpResponseMessage(responseCode)
{
Content = new StringContent(responseString, Encoding.UTF8, "application/json")
};
return responseMsg;
}

Categories