How to send parameter in REST api in xamarin.forms? - c#

How to send parameter in REST api in xamarin.forms ?
I have created REST API Project in xamarin using PCL.
When I call Simple REST api using Below code in Xamarin.forms (Portable Class Library) then I have Successfully receive json Response.
using (var cl = new HttpClient())
{
var result = await cl.GetStringAsync("http://192.168.1.100/apps/jara/web/api/user/test");
jsonResponseClass des = JsonConvert.DeserializeObject<jsonResponseClass>(result);
lbl1.Text = des.code + " " + des.status + " " + des.message;
}
public class jsonResponseClass
{
public string code { get; set; }
public string status { get; set; }
public string message { get; set; }
}
Using above code I got a response
{
code: 200,
status: "ok",
message: "hello"
}
REST API response type is JSON and type is POST
Now, I want to call below Login Api using paramater.
http://192.168.1.100/apps/jara/web/api/user/login
Paramater : email_id and Password
this api success response type is....
{
code: 200,
status: "Success",
User: {
userid: 126,
token: "d154s4d54s654df5s4df56s4df564s5df4",
email: "shahbuddin#gmail.com",
mobile_number: "9898989898"
},
message: "Successfully logged in"
}
What can i do ?

Finally i can do this using below code....
using (var cl = new HttpClient())
{
var formcontent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string,string>("email_id","shahbuddin#peerbits.com"),
new KeyValuePair<string, string>("password","shah")
});
var request = await cl.PostAsync("http://192.168.1.100/apps/jara/web/api/user/login", formcontent);
request.EnsureSuccessStatusCode();
var response = await request.Content.ReadAsStringAsync();
jsonResponselogin res = JsonConvert.DeserializeObject<jsonResponselogin>(response);
lbl1.Text = res.code + " " + res.status + " " + res.message;
}
This code helpful for Calling REST API with Parameter
Thank you...

Related

Issues with Cefsharp and foreach loop

I'm new to working with async and I'm trying to build a Cefsharp application that collects data from an external API, stores it in local variables and then exports these through JavaScript to HTML. It's not a beautiful implementation and I'm sure my code is pretty awful but here goes:
My application performs a tick every 5 seconds, where it executes a HTTP Post request and stores the result in a QuickType (app.quicktype.io) list. This is the tick:
private async void timer1_Tick(object sender, EventArgs e)
{
await chromeBrowser.WaitForInitialLoadAsync();
if (httpPost.ConnectionSuccesful())
{
var devtoolsContext = await chromeBrowser.CreateDevToolsContextAsync();
var postResult = await httpPost.SendPost("robot_info");
try {
var result = Welcome.FromJson(postResult);
foreach (var robot in result.Result.Robots.Select((value, i) => (value, i)))
{
Console.WriteLine(robot.value.Id);
if (robot.value.ChargingStateCode == 9 || robot.value.ChargingStateCode == 12)
await devtoolsContext.EvaluateFunctionAsync("function setBatteryCharge() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', "+ robot.value.StateOfCharge + " + '%'); batteryLevel.text('Charging'); batteryLevel.addClass('high'); batteryLevel.removeClass('medium'); batteryLevel.removeClass('low'); }");
else if (robot.value.StateOfCharge > 75)
await devtoolsContext.EvaluateFunctionAsync("function setBatteryHigh() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', " + robot.value.StateOfCharge + " + '%'); batteryLevel.text(" + robot.value.StateOfCharge + " + '%'); batteryLevel.addClass('high'); batteryLevel.removeClass('medium'); batteryLevel.removeClass('low'); }");
else if (robot.value.StateOfCharge >= 50)
await devtoolsContext.EvaluateFunctionAsync("function setBatteryMedium() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', " + robot.value.StateOfCharge + " + '%'); batteryLevel.text(" + robot.value.StateOfCharge + " + '%'); batteryLevel.addClass('medium'); batteryLevel.removeClass('high'); batteryLevel.removeClass('low'); }");
else
await devtoolsContext.EvaluateFunctionAsync("function setBatteryLow() { var batteryLevel = jQuery('#robot" + robot.i + "Charge'); batteryLevel.css('width', " + robot.value.StateOfCharge + " + '%'); batteryLevel.text(" + robot.value.StateOfCharge + " + '%'); batteryLevel.addClass('low'); batteryLevel.removeClass('high'); batteryLevel.removeClass('medium'); }");
}
}
catch (ArgumentNullException Nex) {
Console.Write("[Error] - " + Nex.Message);
}
catch (Exception ex)
{
Console.WriteLine("[Error] - " + ex.Message);
}
}
else
Console.WriteLine("[Error] - Check connection or access to API server.");
}
I'm currently trying to update the battery level and it successfully does this for the first tick (the JavaScript works as intended and both the css, classes and text is changed). Then it stops working. I've checked that the correct results are coming in from the HTTP Post and that the data is stored properly in the local variables. The problem seems to occur in the foreach. I've tried to read up about async a bit but I can't seem to find the culprit. After the first execution of the code, something seems to be blocking the iteration of the for each. I'm using Cefsharp.Winforms and Cefsharp.Puppeteer.
Any idea on why this is happening? Also thankful for any pointers or tips on how to improve the code.
EDIT: This is the Console Output
[Query] Sending post request to xxx with method 'robot_info'
[Success] - API Post Request was succesful.
PR1#11
PR1#15
[Query] Sending post request to xxx with method 'robot_info'
[Success] - API Post Request was succesful.
PR1#11
[Query] Sending post request to xxx with method 'robot_info'
[Success] - API Post Request was succesful.
PR1#11
The first iteration goes through fine.
EDIT2: This is the timer
public void InitTimer()
{
timer1 = new Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 5000;
timer1.Start();
}
EDIT3: Method SendPost
public async Task<string> SendPost(string method)
{
HttpClient httpClient = new HttpClient();
string data = new JavaScriptSerializer().Serialize(new
{
jsonrpc = "2.0",
method = method,
id = Guid.NewGuid().ToString()
});
StringContent content = new StringContent(data, System.Text.Encoding.UTF8, "application/json");
try
{
Console.WriteLine("[Query] Sending post request to " + url.ToString() + " with method '" + method + "'");
HttpResponseMessage response = await httpClient.PostAsync(url, content).ConfigureAwait(false);
string result = await response.Content.ReadAsStringAsync();
if (IsValidJson(result))
{
Console.WriteLine("[Success] - API Post Request was succesful.");
return result;
}
else
return null;
} catch (HttpRequestException hre)
{
Console.WriteLine("[Error]: " + hre);
return null;
}
}
EDIT4: Structure of Welcome
public partial class Welcome
{
[JsonProperty("jsonrpc")]
public string Jsonrpc { get; set; }
[JsonProperty("result")]
public Result Result { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
}
public partial class Result
{
[JsonProperty("timestamp")]
public long Timestamp { get; set; }
[JsonProperty("robots")]
public List<Robot> Robots { get; set; }
}
Robots is a list with a bunch of longs and ints.

Instagram Api (https://api.instagram.com/oauth/access_token" , "post" , parameters) returns 400 Bad Request

I am developing an app using instagram api to bring feed to my website. I have following code but when i try to access the access_token using the code provided by Instagram it's giving me `400 Bad request error. I would be much obliged if someone could help me to overcome this problem. Many Thanks
string code="";
public ActionResult Index()
{
if (!String.IsNullOrEmpty(Request["code"]))
{
code = Request["code"].ToString();
GetDataInstagramToken();
}
return View();
}
public ActionResult Instagram()
{
var client_id = ConfigurationManager.AppSettings["instagram.clientid"].ToString();
var redirect_uri = ConfigurationManager.AppSettings["instagram.redirecturi"].ToString();
string url = "https://api.instagram.com/oauth/authorize/?client_id=" + client_id + "&redirect_uri=" + redirect_uri + "&response_type=code";
Response.Redirect(url);
return View();
}
public void GetDataInstagramToken()
{
var json = "";
var page = HttpContext.CurrentHandler as Page;
try
{
NameValueCollection parameters = new NameValueCollection();
parameters.Add("client_id", ConfigurationManager.AppSettings["instagram.clientid"].ToString());
parameters.Add("client_secret", ConfigurationManager.AppSettings["instagram.clientsecret"].ToString());
parameters.Add("grant_type", "authorization_code");
parameters.Add("redirect_uri", ConfigurationManager.AppSettings["instagram.redirecturi"].ToString());
parameters.Add("code", code);
WebClient client = new WebClient();
var result = client.UploadValues("https://api.instagram.com/oauth/access_token", "post", parameters);
var response = System.Text.Encoding.Default.GetString(result);
// deserializing nested JSON string to object
var jsResult = (JObject)JsonConvert.DeserializeObject(response);
string accessToken = (string)jsResult["access_token"];
int id = (int)jsResult["user"]["id"];
//This code register id and access token to get on client side
page.ClientScript.RegisterStartupScript(this.GetType(), "GetToken", "<script> var instagramaccessid=\"" + #"" + id + "" + "\"; var instagramaccesstoken=\"" + #"" + accessToken + "" + "\";</script>");
}
catch (Exception ex)
{
throw;
}
}
I am getting exception at
var result = client.UploadValues("https://api.instagram.com/oauth/access_token", "post", parameters);
In this line
client.UploadValues("https://api.instagram.com/oauth/access_token", "post", parameters);
You don't send any value to Instagram. If you check your parameter you can see your key but you cant see any value.
Try this:
public async void GetTokenFromCode()
{
var values = new Dictionary<string, string> {
{ "client_id","Your ChatId" },
{ "client_secret", "Your Client Secret" },
{ "grant_type", "authorization_code" },
{ "redirect_uri", "Your Redirect url"},
{ "code", "code" } };
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://api.instagram.com/oauth/access_token", content);
var responseString = await response.Content.ReadAsStringAsync();
}

Asp.net WebApi method instead of AngularJs Service

I have written Angularjs service as shown below.It retrieves data from the 3rd party service.It's working fine.
Now I have a requirement to write a WebApi method for the same.The reason for that is, we can consume that service from various types of applications.i.e. desktop, web and mobile.How can I implement such a service?
AngulaJS service:
(function () {
appModule.service('getPropertyDetailsByUsingApiService', ['$http', function ($http) {
this.propertyDetails = function (token, number, street, county, zip) {
var endpointUrl = 'http://myaddress.com/api/AddressMatcher?Token=';
var url = endpointUrl + token + '&Number=' + number + '&Street=' + street + '&County=' + county + '&Zip=' + zip;
return $http.get(url).then(function (data) {
var result = data;
if (result.data[0].Status == 'OK') {
return $http.get(endpointUrl + token + '&Apn=' + result.data[0].Result[0].APN + '&County=' + county)
.then(function (finalData) {
return finalData;
});
} else {
return null;
}
});
};
}
]);
})();
WebApi method :
[HttpGet]
public async Task<MyModelDto> GetPropertyDetailsByUsingApiService()
{
//I would like to have a help here to implement it
return result;
}
I guess you are looking for HttpClient.GetAsync.
For example,
var response = await client.GetAsync("http://...");
if (response.IsSuccessStatusCode) {
...
}
Use this,
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(apiDetails.BaseUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.PostAsJsonAsync(apiDetails.RequestUrl, obj).Result;
}

Send Push Notification from a device via Azure NotificationHub REST Api

I am trying to send a push notification from an iOS device (iPhone) via Azure NotificationHub REST Api. I am attempting this from a Xamarin.iOS solution following the Azure documentation I found online.
Response returns following info:
Error: '50002: Provider Internal Error'
Status code: 500
Code used to invoke NotificationHub REST Api (from iOS client app):
var hubUtil = new NotificationHubUtility("Endpoint=sb://company-name.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=00000000000000011111111111111122222222222222");
hubUtil.SendNotificationMessage("This is a TEST Notification!").ConfigureAwait(false);
public class NotificationHubUtility
{
public string Endpoint { get; private set; }
public string SasKeyName { get; private set; }
public string SasKeyValue { get; private set; }
public string HubName { get; private set; }
public string ApiVersion { get; private set; }
public NotificationHubUtility(string connectionString)
{
//Parse Connectionstring
string[] parts = connectionString.Split(new char[] {';'});
for (int i = 0; i < parts.Length; i++)
{
if (parts[i].StartsWith("Endpoint", StringComparison.CurrentCulture))
Endpoint = "https" + parts[i].Substring(11);
if (parts[i].StartsWith("SharedAccessKeyName", StringComparison.CurrentCulture))
SasKeyName = parts[i].Substring(20);
if (parts[i].StartsWith("SharedAccessKey", StringComparison.CurrentCulture))
SasKeyValue = parts[i].Substring(16);
}
HubName = "my-hub";
ApiVersion = "?api-version=2014-09-01";
}
public string GetSaSToken(string uri, int minUntilExpire)
{
string targetUri = Uri.EscapeDataString(uri.ToLower()).ToLower();
// Add an expiration in seconds to it.
long expiresOnDate = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
expiresOnDate += minUntilExpire * 60 * 1000;
long expires_seconds = expiresOnDate / 1000;
var toSign = targetUri + "\n" + expires_seconds;
// Generate a HMAC-SHA256 hash or the uri and expiration using your secret key.
IMacAlgorithmProvider hasher = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha256);
var messageBuffer = WinRTCrypto.CryptographicBuffer.ConvertStringToBinary(toSign, Encoding.UTF8);
var keyBuffer = WinRTCrypto.CryptographicBuffer.ConvertStringToBinary(SasKeyValue, Encoding.UTF8);
var hmacKey = hasher.CreateKey(keyBuffer);
var signedMessage = WinRTCrypto.CryptographicEngine.Sign(hmacKey, messageBuffer);
string signature = Uri.EscapeDataString(WinRTCrypto.CryptographicBuffer.EncodeToBase64String(signedMessage));
var token = "SharedAccessSignature sig=" + signature + "&se=" + expires_seconds + "&skn=" + SasKeyName + "&sr=" + targetUri;
return token;
}
public async Task SendNotificationMessage(string message)
{
try
{
// basic http client (if needed)
var httpClient = new HttpClient();
httpClient.MaxResponseContentBufferSize = 1024000;
var notificationPayload = "{\"aps\":{\"alert\":\"" + message + "\"}}";
var notificationHubUrl = $"{Endpoint}{HubName}/messages/{ApiVersion}";
var authToken = GetSaSToken(notificationHubUrl, 10);
var request = new HttpRequestMessage(HttpMethod.Post, notificationHubUrl);
//request.Headers.Add("Content-Type", "application/json;charset=utf-8");
request.Headers.Add("ServiceBusNotification-Format", "apple");
request.Headers.Add("ServiceBusNotification-Apns-Expiry", DateTime.UtcNow.AddYears(1).ToString("YYYY-MM-DDThh:mmTZD"));
request.Headers.Add("Authorization", authToken);
var requestBody = new StringContent(notificationPayload, Encoding.UTF8, "application/json");
request.Content = requestBody;
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead);
}
catch (Exception ex)
{
Console.Error.WriteLine(#"ERROR - Sending Notification {0}", ex.Message);
}
}
}
Example of Connection String:
Endpoint=sb://company-name.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=00000000000000011111111111111122222222222222
Environment and Assumptions:
Xamarin.iOS solution using C#
Using PCLCrypto library for encryption
I am attempting to recreate the solution demonstrated in an Example in Azure examples github repo but using Xamarin.iOS
The connection string is taken directly from Azure portal
The code for generating SaS token is adapted from Azure NotificationHub REST Api Documentation
Notification hub works, I am able to send a test push notification through the hub UI and i see it come in on the device
What am I missing here? I wasn't able to find much relevant documentation for this error online. Any help would be greatly appreciated.
Update with Fix:
The following 2 changes to the code above fixed the issue for me:
Changed
ApiVersion = "?api-version=2014-09-01";
to
ApiVersion = "?api-version=2016-07";
Changed
request.Headers.Add("ServiceBusNotification-Apns-Expiry", DateTime.UtcNow.AddYears(1).ToString("YYYY-MM-DDThh:mmTZD"));
to
request.Headers.Add("ServiceBusNotification-Apns-Expiry", DateTime.UtcNow.AddYears(1).ToString("yyyy-MM-ddTHH:mm:sszzz"));
The Api Version 2014-09-01 is not correct. Please use 2016-07 as the Api version and you should be good.
Thanks
Sohrab
I've figured out the issue(s):
+1 to Sohrab for pointing out the Api Version, I updated it to ApiVersion = "?api-version=2016-07";
There was an error in the ServiceBusNotification-Apns-Expiry header value format, the date was not being correctly formatted to string. Corrected format string is this ToString("yyyy-MM-ddTHH:mm:sszzz")

Show Json Data obtained from PHP File in Windows Phone 8.1

I have PHP file which gives me following JSON:
{"Name":"Waqas","Age":37,"Address":"Kanju"}
When I execute this method in Windows Phone it gives me the same JSON:
{"Name":"Waqas","Age":37,"Address":"Kanju"}
in textblock named tblock.Text;
This is my method for receiving data from PHP file in JSON format:
public async void sndandrec(string feedingaddress, HttpResponseMessage response, TextBlock tblock, HttpClient myhttpClient)
string responseText;
tblock.Text = "Waiting for response ...";
try
{
response = await myhttpClient.GetAsync(resourceUri);
response.EnsureSuccessStatusCode();
responseText = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
// Need to convert int HResult to hex string
tblock.Text = "Error = " + ex.HResult.ToString("X") +
" Message: " + ex.Message;
responseText = "";
}
tblock.Text = response.StatusCode + " " + response.ReasonPhrase;
tblock.Text = responseText.ToString();
This is my class:
public class RootObject
{
public string Name { get; set; }
public int Age { get; set; }
public int Address { get; set; }
}
I would like to show the Name value in TextboxName, similary Age value in TextboxAge and Address value in TextboxAddress. I don't know how to do that.
Okay, major edit, and I basically removed all of my last answer because of it being incorrect.
Reference a JSON library, the easiest is to search for JSON.NET on NuGet and reference that. Then you can make a call to your server and parse the JSON data.
WebRequest request = WebRequest.Create("http://addresstojson.com/json.json");
WebResponse response = await request.GetResponseAsync();
using(var stream = new StreamReader(response.GetResponseStream()))
{
json = JsonConvert.DeserializeObject<RootObject>(stream.ReadToEnd());
}
Then you can still set the textblocks with the data retrieved using your RootObject class you defined in your question
tbName.Text = "Name: " + json.Name;
tbAge.Text = "Age: " + json.Age;
tbAddress.Text = "Address: " + json.Address;
Here is the JSON I used for this example:
{
"name": "John Doe",
"age": 25,
"Address": "Mars"
}

Categories