I managed to get the token through this guide: https://platform.fatsecret.com/api/Default.aspx?screen=rapiauth2, but I couldn't get responce correctly. Where did I go wrong in the code?
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private async void BtnFoodApi_Click(object sender, RoutedEventArgs e)
{
// --- Get Token --
HttpClient client = new HttpClient();
var byteArray = Encoding.ASCII.GetBytes("9276456b47524b479cbdaf7cf5792bbf:0366d2fc646e4b6f89bf11bddbaec6a4");
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
var values = new Dictionary<string, string>
{
{ "scope", "basic" },
{ "grant_type", "client_credentials" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://oauth.fatsecret.com/connect/token", content);
var responseString = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(responseString));
var data = (RootObject)serializer.ReadObject(ms);
// --- Get responce --
var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", data.access_token);
var valuesRequest = new Dictionary<string, string>
{
{ "application", "json" },
};
var contentRequest = new FormUrlEncodedContent(valuesRequest);
var responseRequest = await http.PostAsync("https://platform.fatsecret.com/rest/server.api", contentRequest);
//Parameters: method=foods.search&search_expression=toast&format=json // How can I call Api 2.0 with these parameters?
//var responseRequestString = await responseRequest.Content.ReadAsStringAsync();
}
}
[DataContract]
public class RootObject
{
[DataMember]
public string access_token { get; set; }
[DataMember]
public int expires_in { get; set; }
[DataMember]
public string token_type { get; set; }
}
I would like to get to the responseRequest String string in Json string.
At the bottom of this page there is the guide about this step and I tried to write it in c # but incorrectly.
Thanks in advance!
You don't need to base64-encode your Bearer token - that's only used to obfuscate Basic authentication. You can use the string as-is.
http.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", data.access_token);
Related
I tried many time today to call a web api function with POST (HttpClient.PostAsync) method . But unfortunately I can't.
Only the call with GET (HttpClient.GetAsync) method working with success.
I try to follow many sample on the net, but always the same error. ("Not Found")
Thank you so much if somebody can help me
Here is the C# Web API:
[RoutePrefix("NewAreaMap")]
public class NewAreaMapController: ApiController
{
[HttpPost]
[ActionName("PostCreateAreaTemp")]
public AreaTemp PostCreateAreaTemp(double southLatitude, double westLongitude, double northLatitude, double eastLongitude, int countryId, int worldId)
{
AreaTemp newTempMap = new AreaTemp();
//.....
* * Here is the C# code from client side: * *
using(var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["SrvWebApiPath"].ToString());
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var values = new Dictionary < string,
string > ()
{
{
"southLatitude", southLatitude.ToString()
},
{
"westLongitude", westLongitude.ToString()
},
{
"northLatitude", northLatitude.ToString()
},
{
"eastLongitude", eastLongitude.ToString()
},
{
"countryId", countryId.ToString()
},
{
"worldId", worldId.ToString()
}
};
var content = new FormUrlEncodedContent(values);
HttpResponseMessage response = await client.PostAsync("api/NewAreaMap/PostCreateAreaTemp", content)
if (response.IsSuccessStatusCode)
{
string jsonData = response.Content.ReadAsStringAsync().Result;
newAreTemp = JsonConvert.DeserializeObject < AreaTemp > (jsonData);
}
}
The GET call work well with the following Url :
HttpResponseMessage response = await client.GetAsync("api/NewAreaMap/GetAreaTemp/?latitudeAreaCenter=7.02&longitudeAreaCenter=9.05");
Since you're posting a JSON, you might as well send it as an object. Or if you still want to keep the dictionary and the signature for the method you could try:
var content = new StringContent(JsonConvert.SerializeObject(values),
Encoding.UTF8, "application/json");
Instead of
var content = new FormUrlEncodedContent(values);
Here's an example with an object.
public class SampleObject
{
public double SouthLatitude { get; set; }
public double WestLongitude { get; set; }
public double NorthLatitude { get; set; }
public double EastLongitude { get; set; }
public int CountryId { get; set; }
public int WorldId { get; set; }
}
And change your request.
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["SrvWebApiPath"].ToString());
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var obj = new SampleObject
{
SouthLatitude = southLatitude,
WestLongitude = westLongitude,
NorthLatitude = northLatitude,
EastLongitude = eastLongitude,
CountryId = countryId,
WorldId = worldId
};
// Send it as StringContent.
var request = new StringContent(JsonConvert.SerializeObject(obj),
Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync("api/NewAreaMap/PostCreateAreaTemp", request)
if (response.IsSuccessStatusCode)
{
string jsonData = response.Content.ReadAsStringAsync().Result;
newAreTemp = JsonConvert.DeserializeObject<AreaTemp>(jsonData);
}
}
And the signature on the server.
public AreaTemp PostCreateAreaTemp(SampleObject sampleObject)
Or if needed:
public AreaTemp PostCreateAreaTemp([FromBody]SampleObject sampleObject)
replace your method parameter with object because you are passing full object
"content" from the httpclient so in that case you need to use same object here also with [frombody] attribute
methodname([FromBody] Content content)
define all the properties in one class and use . Hope it will helpful for you.
Please try to use FromBody attribute with your action parameter.
So I create an HttpPut method in an ASP.NET web api.
[Route("api/Account/Save")]
[HttpPut]
public IHttpActionResult SaveAccount(Account acc) {
// do stuff
}
I pass in an instant of the Account class.
class Account
{
public int AccountID { get; set; }
public string AccountName { get; set; }
}
Now I want to call this from a console application. I am trying to do this but it's not working. It's not throwing any exception either.
var acc = new Account() { AccountID = 1234, AccountName = "zzzzP" };
string json = JsonConvert.SerializeObject(acc);
HttpContent content = new StringContent(json);
response = await client.PutAsync("api/Account/Save", content);
Json returned:
"{\"AccountID\":1234,\"AccountName\":\"zzzzP\"}"
You probably want something like this
static async Task PutAccount()
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://yourWebSite.com");
var acc = new Account() { AccountID = 1234, AccountName = "zzzzP" };
string json = JsonConvert.SerializeObject(acc);
using (HttpResponseMessage response = await client.PutAsync("api/Account/Save", new StringContent(json)))
{
return response.EnsureSuccessStatusCode();
}
}
}
I have this code:
private const string route = "/api/Print";
public bool Update(string header, string tc)
{
bool success = false;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("my uri");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var print = new Print { CompanyRef = new Guid(), Header = header, TC = tc };
var response = client.PutAsJsonAsync(route, print);
}
success = true;
return success;
}
public sealed class Print
{
public string Header { get; set; }
public string TC { get; set; }
public System.Guid CompanyRef { get; set; }
}
I call it like so:
Update(" header", " string tc");
In C# desktop app it works.
In Windows 10 IoT on a Raspberry Pi2 device it does not work.
Yet, when i am calling a Get from my Web API server *in Iot) it works fine.
?
I am using this code for a year now and it works:
using Windows.Web.Http;
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
try
{
var o = new
{
operation = "NewEvent",
location_id = locationID,
eventName = eventName
};
HttpStringContent content = new HttpStringContent(JsonConvert.SerializeObject(o), Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json");
HttpResponseMessage response = await httpClient.PostAsync(new Uri(urlPostData), content);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
// TODO: Do something with the responseBody
}
catch (Exception)
{
// TODO: Deal with exception - could be a server not found, 401, 404, etc.
}
}
I'm trying to retrieve an access token from Google's authorization endpoint, however I keep getting 401: Unauthorized.
I'm pretty sure all the values being sent (authorization code, client's id, client's secret, redirect uri and grant type) are correct.
My code is the following:
using (HttpClient client = new HttpClient()) {
IEnumerable<KeyValuePair<string,string>> data = new List<KeyValuePair<string,string>>
{
new KeyValuePair<string,string>("code", "CODE_HERE"),
new KeyValuePair<string,string>("client_id", "CLIENT_ID_HERE"),
new KeyValuePair<string,string>("client_secret", "CLIENT_SECRET_HERE"),
new KeyValuePair<string,string>("redirect_uri", "REDIRECT_URI_HERE"),
new KeyValuePair<string,string>("grant_type", "authorization_code"),
}
HttpContent content = new FormUrlEncodedContent(data);
/* I'm getting 401 Unauthorized */
HttpResponseMessage response = await client.PostAsync("https://www.googleapis.com/oauth2/v3/token", content);
}
The response's JSON is:
{
"error": "invalid_client",
"error_description": "Unauthorized"
}
However, I'm copying & pasting the client's id and client's secret from my Google Developer control panel, so there is no way they are wrong.
Any help?
Here is what worked for me. In this sample, I'm using the RefreshToken to get an AccessToken.
var client_id = ConfigurationManager.AppSettings.Get("GoogleClientId");
var client_secret = ConfigurationManager.AppSettings.Get("GoogleSecret");
var grant_type = "refresh_token";
var url = "https://www.googleapis.com/oauth2/v4/token";
IEnumerable<KeyValuePair<string, string>> data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string,string>("client_id", client_id),
new KeyValuePair<string,string>("client_secret", client_secret),
new KeyValuePair<string,string>("grant_type", grant_type),
new KeyValuePair<string,string>("refresh_token", refreshToken),
};
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
HttpContent contentPost = new FormUrlEncodedContent(data);
HttpResponseMessage response = await client.PostAsync(url, contentPost);
var result = response.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<GoogleAPIAuth>(result);
Here is my GoogleAPIAuth class.
public class GoogleAPIAuth
{
public string client_secret { get; set; }
public string grant_type { get; set; }
public string refresh_token { get; set; }
public string client_id { get; set; }
public string access_token { get; set; }
public string expires_in { get; set; }
public string token_type { get; set; }
}
I have a a view model that looks like.
public class StoreItemViewModel
{
public Guid ItemId { get; set; }
public List<Guid> StoreIds { get; set; }
[Required]
public string Description { get; set; }
//[Required]
//[DataMember(IsRequired = true)]
public int ItemTypeId { get; set; }
}
I have a small helper that using is using RestSharp.
public static IRestResponse Create<T>(object objectToUpdate, string apiEndPoint) where T : new()
{
var client = new RestClient(CreateBaseUrl(null))
{
Authenticator = new HttpBasicAuthenticator("user", "Password1")
};
var request = new RestRequest(apiEndPoint, Method.POST);
//request.JsonSerializer = new JsonSerializer();
// {RequestFormat = DataFormat.Json};
request.AddObject(objectToUpdate);
// clientJsonSerializer = new YourCustomSerializer();
var response = client.Execute<T>(request);
return response;
}
When debugging the controller within my api
[HttpPost]
public HttpResponseMessage Create([FromBody]StoreItemViewModel myProduct)
{
//check fields are valid
.........
}
myProducts products are all populated apart from the public List StoreIds it always is returning a single reward with an empty Guid. Even if I have added 2 or more StoreIds
I assume this is because I am doing something wrong with my Create helper within my application.
Can anyone help with this its causing a major headache.
The raw data sent to the webapi is looking like
ItemId=f6dbd244-e840-47e1-9d09-53cc64cd87e6&ItemTypeId=6&Description=blabla&StoreIds=d0f36ef4-28be-4d16-a2e8-37030004174a&StoreIds=f6dbd244-e840-47e1-9d09-53cc64cd87e6&StoreId=d0f36ef4-28be-4d16-a2e8-37030004174a
RestSharp now has a more streamlined way to add an object to the RestRequest Body with Json Serialization:
public static IRestResponse Create<T>(object objectToUpdate, string apiEndPoint) where T : new()
{
var client = new RestClient(CreateBaseUrl(null))
{
Authenticator = new HttpBasicAuthenticator("user", "Password1")
};
var request = new RestRequest(apiEndPoint, Method.POST);
request.AddJsonBody(objectToUpdate); // HERE
var response = client.Execute<T>(request);
return response;
}
This was found in RestSharp 105.0.1.0
I managed to get this working. I don't think its the correct way but it works.
public static IRestResponse Create<T>(object objectToUpdate, string apiEndPoint) where T : new()
{
var client = new RestClient(CreateBaseUrl(null))
{
Authenticator = new HttpBasicAuthenticator("user", "Password1")
};
var json = JsonConvert.SerializeObject(objectToUpdate);
var request = new RestRequest(apiEndPoint, Method.POST);
request.AddParameter("text/json", json, ParameterType.RequestBody);
var response = client.Execute<T>(request);
return response;
}
I struggled with the same problem and came up a working solution.
Be sure to set the request format to JSON:
request.RequestFormat = DataFormat.Json;
Use AddBody, rather than AddObject:
request.AddBody(zNewSessionUsage);
So your code would be something like this:
public static IRestResponse Create<T>(object objectToUpdate, string apiEndPoint) where T : new()
{
var client = new RestClient(CreateBaseUrl(null))
{
Authenticator = new HttpBasicAuthenticator("user", "Password1")
};
var request = new RestRequest(apiEndPoint, Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddBody(objectToUpdate);
var response = client.Execute<T>(request);
return response;
}