I'm building a checkout page written in Xamarin Forms that creates an order in Woocommerce.
I've looked up documentation online but can't seem to find any examples or code that shows you how to do this.
My question is : is there an example code on how to create a simple order using Xamarin Forms and Woocommerce REST API?
I was able to use the REST API to pull the products from Woocommerce but can't seem to find any code examples of how to actually create an order using the REST API in Xamarin Forms.
Hope you can help.
Cheers
Here's my code woocommerceapi.cs class.
class WoocommerceAPI
{
private static string website_url = "xxxxx";
private static string consumer_key = "xxxxx";
private static string consumer_secret = "xxxxx";
private static string GetAllProductsApiUrl = string.Format("{0}/wc-api/v3/products?consumer_key={1}&consumer_secret={2}", website_url, consumer_key, consumer_secret);
private static string GetAllProductsInACategoryApiUrl = "xxxxx/wc-api/v3/products?category=379&consumer_key=xxxxx&consumer_secret=xxxxx";
public async Task<Products> GetAllProducts()
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(GetAllProductsApiUrl);
HttpContent content = response.Content;
var json = await content.ReadAsStringAsync();
var products = JsonConvert.DeserializeObject<Products>(json);
return products;
}
public async Task<Products> GetAllProductsInACategory()
{
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(GetAllProductsInACategoryApiUrl);
HttpContent content = response.Content;
var json = await content.ReadAsStringAsync();
var products = JsonConvert.DeserializeObject<Products>(json);
return products;
}
}
I managed to build a solution and it's now working!
Here's the code if you come across this problem and need a fix.
async void OrderBtnClicked(object sender, EventArgs e)
{
Console.WriteLine("Starting REST API");
var clientapi = new HttpClient();
clientapi = new Uri("xxxx?consumer_key=xxxx&consumer_secret=xxxx");
Console.WriteLine("Starting REST API");
var clientapi = new HttpClient();
clientapi.BaseAddress = new Uri("xxxx?consumer_key=xxxx&consumer_secret=xxxx");
// json data for adding customer
string jsonData = #"{
""first_name"" : ""John1"",
""last_name"" : ""Doe1"",
""email"" : ""john.doe1#example.com"",
""username"" : ""john.doe1"",
""password"" : ""mypassword"",
""billing"": {
""first_name"": ""John"",
""last_name"": ""Doe"",
""company"": ""john doe company"",
""address_1"": ""969 Market"",
""address_2"": """",
""city"": ""San Francisco"",
""state"": ""CA"",
""postcode"": ""94103"",
""country"": ""US"",
""email"": ""john.doe#example.com"",
""phone"": ""(555) 555-5555""
},
""shipping"": {
""first_name"": ""John"",
""last_name"": ""Doe"",
""company"": """",
""address_1"": ""969 Market"",
""address_2"": """",
""city"": ""San Francisco"",
""state"": ""CA"",
""postcode"": ""94103"",
""country"": ""US""
}
}";
Console.WriteLine("Here's the json string data");
Console.WriteLine(jsonData);
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage apiresponse = await clientapi.PostAsync("xxxxx?consumer_key=xxxxx&consumer_secret=xxxx", content);
var apiresult = await apiresponse.Content.ReadAsStringAsync();
Console.WriteLine("Here's the result:");
Console.WriteLine(apiresult);
Console.WriteLine("REST API Post Completed.");
await DisplayAlert("Checkout", "Completed", "ok");
}
Obviously you can setup public variables to store the json data and you're more than welcome to do so, i'm not your dad.
Related
My controller code is lke this,
public async Task<IEnumerable<CalendarEvent>> Get()
{
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "xxxxx";
var clientId = "xxxxxx";
var clientSecret = "xxxx";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var graphServiceClient = new GraphServiceClient(clientSecretCredential, scopes);
if (User == null!)
{
var user = await graphServiceClient.Users["xxxxx.com"].Calendar
.Events
.Request()
.Select("subject,body,bodyPreview,organizer,attendees,start,end,location")
.GetAsync();
return (CalendarEvent)user;
}
}
Iam getting an error like
Unable to cast object of type 'Microsoft.Graph.CalendarEventsCollectionPage' to type 'System.Collections.Generic.IEnumerable'
I need query that sholud be given in controller.
It's not exactly clear what you are trying to achieve but you can't convert CalendarEventsCollectionPage to IEnumerable. I am assuming that you want to return all events of specific user.
public async Task<List<Event>> GetEventsOfUser(string userId)
{
var events = new List<Event>();
var eventsPages = _client.Users[userId].Calendar.Events.Request()
.Select("subject,body,bodyPreview,organizer,attendees,start,end,location");
while (eventsPages != null)
{
var current = await eventsPages.GetAsync();
events.AddRange(current.CurrentPage);
eventsPages = current.NextPageRequest;
}
return events;
}
You need to fetch every page with NextPageRequest in order to get all events.
I have Generated Microsoft Graph app in ASP.NET MVC platform, that I have downloaded from Microsoft Graph site. I need to access the shared mail folder not sure exactly how can I get that?? In the following code I can access my mailFolder but not shared mailfolder!
public static async Task<IEnumerable<MailFolder>> GetMailFolderAsync()
{
var graphClient = GetAuthenticatedClient();
var mailFolder = await graphClient.Me.MailFolders.Request().GetAsync();
var sharedMailFolder = await graphClient.Users.Request().GetAsync();
return mailFolder;
}
Also, I want to know in above code where I can pass the parameter to access next page or all pages??
private static GraphServiceClient GetAuthenticatedClient()
{
return new GraphServiceClient(
new DelegateAuthenticationProvider(
async (requestMessage) =>
{
string signedInUserId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
SessionTokenStore tokenStore = new SessionTokenStore(signedInUserId,
new HttpContextWrapper(HttpContext.Current));
var idClient = new ConfidentialClientApplication(
appId, redirectUri, new ClientCredential(appSecret),
tokenStore.GetMsalCacheInstance(), null);
var accounts = await idClient.GetAccountsAsync();
var result = await idClient.AcquireTokenSilentAsync(
graphScopes.Split(' '), accounts.FirstOrDefault());
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", result.AccessToken);
}));
I think it is not possible to access shared folders I am investigating as well. In regards to the question of getting pages, as soon as you get the first request
public static async Task<IEnumerable<MailFolder>> GetMailFolderAsync()
{
var graphClient = GetAuthenticatedClient();
var mailFolder = await graphClient.Me.MailFolders.Request().GetAsync();
var sharedMailFolder = await graphClient.Users.Request().GetAsync();
return mailFolder;
}
then you can review for example, mailFolder.NextPageRequest, if it is not null then you can request it by doing mailFolder.NextPageRequest.GetAsync() and you can use it as a loop conditional
while(mailfoldersCollection != null) {
// Do your stuff with items within for(var folder in mailfoldersCollection) {}
// when read all items in CurrentPage then
if (mailFolder.NextPageRequest != null) {
mailfoldersCollection = await mailFolder.NextPageRequest.GetAsync();
}
hope it works for you!
Is anyone still using the Yahoo Fantasy Sports API? I had an app that worked last year, have not changed my code at all, and now it is returning a 500 internal error when I try to run it.
I used to test things through the YQL Console, but that is no longer available.
https://developer.yahoo.com/yql/
Anyone know how to make authenticated requests on that site above?
My feeling is that Yahoo has just discontinued support for their FantasySports API, I will have to look for other solutions I think.
Wondering if anyone else out there used this API previously and is or is not still having success with it.
I figured out how to use C# core and Yahoo's API. Huge thanks to this guy
Get your api key etc from yahoo.
Make a controller action that redirects to the request URL something like this:
public IActionResult Test()
{
yo.yKey = {your Yahoo API key};
yo.ySecret = {your Yahoo API secret};
yo.returnUrl = {your return URL as set in the API setup, example "https://website.com/home/apisuccess"};
var redirectUrl = "https://api.login.yahoo.com/oauth2/request_auth?client_id=" + yo.yKey + "&redirect_uri=" + yo.returnUrl + "&response_type=code&language=en-us";
return Redirect(redirectUrl);
}
This will send you to a site that authenticates with Yahoo. Upon successful authentication it is going to send you to your redirect site with a string parameter called code, in the example it would be home/apisuccess, so that controller action should look like this:
public async Task<IActionResult> ApiSuccess(string code)
{
List<string> msgs = new List<string>(); //This list just for testing
/*Exchange authorization code for Access Token by sending Post Request*/
Uri address = new Uri("https://api.login.yahoo.com/oauth2/get_token");
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] headerByte = System.Text.Encoding.UTF8.GetBytes(_yKey + ":" + _ySecret);
string headerString = System.Convert.ToBase64String(headerByte);
request.Headers["Authorization"] = "Basic " + headerString;
/*Create the data we want to send*/
StringBuilder data = new StringBuilder();
data.Append("client_id=" + _yKey);
data.Append("&client_secret=" + _ySecret);
data.Append("&redirect_uri=" + _returnUrl);
data.Append("&code=" + code);
data.Append("&grant_type=authorization_code");
//Create a byte array of the data we want to send
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (Stream postStream = await request.GetRequestStreamAsync())
{
postStream.Write(byteData, 0, byteData.Length);
}
// Get response
var vM = new yOauthResponse();
string responseFromServer = "";
try
{
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
msgs.Add("Into response");
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
responseFromServer = reader.ReadToEnd();
msgs.Add(responseFromServer.ToString());
vM = JsonConvert.DeserializeObject<yOauthResponse>(responseFromServer.ToString());
}
}
catch (Exception ex)
{
msgs.Add("Error Occured");
}
ViewData["Message"] = msgs;
return View(vM);
}
Note that I used a json deserializer of this model, but you can do whatever you want with the response to get the data you need out of it. This is my json model:
public class yOauthResponse
{
[JsonProperty(PropertyName = "access_token")]
public string accessToken { get; set; }
[JsonProperty(PropertyName = "xoauth_yahoo_guid")]
public string xoauthYahooGuid { get; set; }
[JsonProperty(PropertyName = "refresh_token")]
public string refreshToken { get; set; }
[JsonProperty(PropertyName = "token_type")]
public string tokenType { get; set; }
[JsonProperty(PropertyName = "expires_in")]
public string expiresIn { get; set; }
}
Once you have that data, the main thing you need is the access_token, and use it as follows in a controller action:
//simple code above removed
var client = new HttpClient()
{
BaseAddress = new Uri({your request string to make API calls})
};
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
HttpResponseMessage response = await client.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
//do what you will with the response....
}
//rest of simple code
Hopefully this helps someone somewhere. Happy coding!
I built a simple Console Application to test the connection to an API. Calling the connection method from Console App Main works fine. I get a response with an access-token.
I though that I just could implement the same method/code to an MVC-project and add the method within the HomeController, then call the method from any ActionResult, getting the access-token and then put it in a ViewBag to display it in a view (just for testing). But it doesn't work in the MVC-project.
If I run the debugger, it seems like the app hangs when SendAsync is executed in the method. The console gives this output:
Application Insights Telemetry (unconfigured): {"name":"Microsoft.ApplicationInsights.Dev.RemoteDependency","time":"2017-04-08T09:26:32.4945663Z","tags":{"ai.internal.sdkVersion":"rddf:2.2.0-738","ai.internal.nodeName":"XXXXXX","ai.cloud.roleInstance":"XXXXXXXX"},"data":{"baseType":"RemoteDependencyData","baseData":{"ver":2,"name":"/token","id":"XXXXXXXXX=","data":"https://api.vasttrafik.se/token","duration":"00:00:00.2810000","resultCode":"200","success":true,"type":"Http","target":"api.vasttrafik.se","properties":{"DeveloperMode":"true"}}}}
The thread 0x1f68 has exited with code 0 (0x0).
What can I do to make the API-call / response work in the MVC-application?
My knowledge in the area is ridiculously low. But I really want to understand whats going on here.
Thanks!
Best
J
MVC project
public class HomeController : Controller
{
public ActionResult Index()
{
string token = PostRequest().Result;
ViewBag.Token = token;
return View();
}
async static Task<string> PostRequest()
{
var client = new HttpClient();
client.BaseAddress = new Uri("https://api.vasttrafik.se");
var request = new HttpRequestMessage(HttpMethod.Post, "/token");
// Key // Secret
string credentials = "xxxxxxxxxoVS5xDrcO6qZsAp0a" + ":" + "xxxxxxxxhn0STj1w4asDwixdMa";
var plainTextBytes = Encoding.UTF8.GetBytes(credentials);
//Key and secret encoded
string encodedCrentedials = Convert.ToBase64String(plainTextBytes);
//Console.WriteLine(encodedCrentedials);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encodedCrentedials);
var formData = new List<KeyValuePair<string, string>>();
formData.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
formData.Add(new KeyValuePair<string, string>("scope", "xxxxxxxxw0oVS5xDrcO6qZsAp0a"));
request.Content = new FormUrlEncodedContent(formData);
// This is where the app hangs....
var response = await client.SendAsync(request);
var mycontentres = await response.Content.ReadAsByteArrayAsync();
var responseBody = Encoding.Default.GetString(mycontentres);
//Console.WriteLine(responseBody);
JavaScriptSerializer seri = new JavaScriptSerializer();
dynamic data = JObject.Parse(responseBody);
string tok = data.access_token;
return tok;
}
}
Don't block on async code:
public async Task<ActionResult> Index()
{
string token = await PostRequest();
ViewBag.Token = token;
return View();
}
I am new to this forum.
I am trying to do Basic authentication using Httclient for my Windows app.
var handler2 = new HttpClientHandler
{
Credentials = new NetworkCredential(username, password)
};
var httpClient2 = new HttpClient(handler2);
httpClient2.DefaultRequestHeaders.Add("user-Agent", "authentication.cs");
var response2 = httpClient.GetAsync(uri);
I have 2 questions:
I need to add header content type and user-agent. Dont know how to add them. Could someone help me out.
In response i am getting null values. Any idea why?
Regards,
TM
You can add the user agent header by doing
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("authentication.cs"));
You can't add Content-Type to the default request headers because you can only set Content-Type when you are sending some Content using a PUT or a POST.
I'm guessing you want to set the Accept header like this:
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
Update: Without my own account, this is as far as I can go.
public sealed partial class MainPage : Page
{
private readonly HttpClient _httpClient = new HttpClient();
public MainPage()
{
this.InitializeComponent();
InitHttpClient();
}
private void InitHttpClient() {
var username = "youremail#somewhere.com";
var password = "yourharvestpassword";
String authparam = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authparam);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
_httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MyHarvestClient", "1.0"));
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e) {
_httpClient.GetAsync("https://yoursubdomain.harvestapp.com/projects")
.ContinueWith(t => HandleResponse(t.Result));
}
private void HandleResponse(HttpResponseMessage response) {
response.EnsureSuccessStatusCode();
var contentString = response.Content.ReadAsStringAsync().Result;
var contentXML = XDocument.Parse(contentString);
}
}