C# object as JavaScript function param - c#

I have next C# code:
public class Login
{
public string UserName { get; set; }
public string Password { get; set; }
public Login(string UserName, string Password)
{
this.UserName = UserName;
this.Password = Password;
}
}
protected const string JsonFunctionFormat = "function {0}(){{ {1}; }}";
protected const string JsonReturnFunctionFormat = "function {0}(){{return {1};}}";
public static void Fill(HtmlDocument Document, string FillerFunctionCode, Login LoginData)
{
if (Document != null)
{
HtmlElement dataElement = Document.CreateElement(OrganizationCardFiller.ScriptHtmlElementName);
IHTMLScriptElement domDataElement = (IHTMLScriptElement)dataElement.DomElement;
domDataElement.text = string.Format(LoginFiller.JsonReturnFunctionFormat, LoginFiller.GetLoginInfoFunctionName, LoginFiller.ConvertToJSon(LoginData));
//domDataElement.text += string.Format(LoginFiller.JsonFunctionFormat, LoginFiller.FillerFunctionName, FillerFunctionCode);
domDataElement.text += FillerFunctionCode;
HtmlElement headElement = Document.GetElementsByTagName(LoginFiller.BodyHtmlElementName)[0];
headElement.AppendChild(dataElement);
//Document.InvokeScript(LoginFiller.FillerFunctionName);
//Document.InvokeScript("FillLoginForm", new object[]{LoginFiller.ConvertToJSon(LoginData)});
//object[] args = { LoginFiller.ConvertToJSon(LoginData) };
//Document.InvokeScript("FillLoginForm", args);
Document.InvokeScript("FillLoginForm", new object[] { "{UserName:'user',Password:'pass'}" });
}
}
private static string ConvertToJSon(object ConvertingObject)
{
System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
return serializer.Serialize(ConvertingObject);
}
And next JavaScript function:
function objToString (obj) {
var str = '';
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str += p + '::' + obj[p] + '\n';
}
}
return str;
}
function FillLoginForm(login)
{
var userName = document.getElementById('ctl00_ctplhMain_Login1_UserName');
var password = document.getElementById('ctl00_ctplhMain_Login1_Password');
alert(objToString({test: 123, test2: '12345'}));
alert(objToString({""UserName"":""username"",""Password"":""veryHardPassword""}));
alert(typeof(login));
alert(login);
alert(objToString(login));
if(userName!=null)
{
userName.value = login.UserName;
}
if(password!=null)
{
password.value=login.Password;
}
}
Alerts with "{test: 123, test2: '12345'}" and "{""UserName"":""username"",""Password"":""veryHardPassword""}" works great, but typeof(login) return "unknown" and "login" with "objToString(login)" return Empty. As you can see, I tryed different variant, but all of them returns Empty. What's I make wrong, why login param don't pass to JavaScript function by correct format?

Related

Object loses data when PutParcable

I created a user class and I initialize it like so:
User MyUser = new User("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
I then populated the object with the user data and to pass it to another activity I do it like so:
Intent intent = new Intent(this, typeof(MyActivity));
Bundle bundlee = new Bundle();
bundlee.PutParcelable("MyUser", MyUser); // Persist user class to next activity
intent.PutExtra("TheBundle", bundlee);
StartActivity(intent);
I then retrieve the user data in the other activity like so:
// I initialize a variable again
User MyUser = new User("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
MyUser = bundlee.GetParcelable("MyUser") as User;
I get all the data EXCEPT Address, City, and State. Weird ... I put breakpoints in the code and its all there when I put it in the bundle, but when I take it out those three fields are null strings. My user class is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Java.Interop;
using Object = Java.Lang.Object;
namespace MyAndroid
{
class User : Object, IParcelable
{
private string mUsername = "";
private string mPassword = "";
private string mFirstname = "";
private string mMiddleInitial = "";
private string mLastname = "";
private string mSuffix = "";
private string mAddress = "";
private string mCity = "";
private string mState = "";
private string mZip = "";
private string mZip4 = "";
private string mHomephone = "";
private string mCellphone = "";
private string mWorkphone = "";
private string mNationalOrgn = "";
private string mCountry = "";
private string mCompany = "";
private string mDepartment = "";
private string mSection = "";
private string mProgram = "";
private string mUsertype = "";
private string mEmailaddress = "";
[ExportField("CREATOR")]
public static UserCreator InitializeCreator()
{
return new UserCreator();
}
// properties
public string Username
{
get
{
return mUsername;
}
set
{
mUsername = value;
}
}
public string Password
{
get
{
return mPassword;
}
set
{
mPassword = value;
}
}
public string Firstname
{
get
{
return mFirstname;
}
set
{
mFirstname = value;
}
}
public string MiddleInitial
{
get
{
return mMiddleInitial;
}
set
{
mMiddleInitial = value;
}
}
public string Lastname
{
get
{
return mLastname;
}
set
{
mLastname = value;
}
}
public string Suffix
{
get
{
return mSuffix;
}
set
{
mSuffix = value;
}
}
public string Address
{
get
{
return mAddress;
}
set
{
mAddress = value;
}
}
public string City
{
get
{
return mCity;
}
set
{
mCity = value;
}
}
public string State
{
get
{
return mState;
}
set
{
mState = value;
}
}
public string Zip
{
get
{
return mZip;
}
set
{
mZip = value;
}
}
public string Zip4
{
get
{
return mZip4;
}
set
{
mZip4 = value;
}
}
public string Homephone
{
get
{
return mHomephone;
}
set
{
mHomephone = value;
}
}
public string Cellphone
{
get
{
return mCellphone;
}
set
{
mCellphone = value;
}
}
public string Workphone
{
get
{
return mWorkphone;
}
set
{
mWorkphone = value;
}
}
public string NationalOrgn
{
get
{
return mNationalOrgn;
}
set
{
mNationalOrgn = value;
}
}
public string Country
{
get
{
return mCountry;
}
set
{
mCountry = value;
}
}
public string Company
{
get
{
return mCompany;
}
set
{
mACompany = value;
}
}
public string Department
{
get
{
return mDepartment;
}
set
{
mDepartment = value;
}
}
public string Section
{
get
{
return mSection;
}
set
{
mSection = value;
}
}
public string Program
{
get
{
return mProgram;
}
set
{
mProgram = value;
}
}
public string Usertype
{
get
{
return mUsertype;
}
set
{
mUsertype = value;
}
}
public string Emailaddress
{
get
{
return mEmailaddress;
}
set
{
mEmailaddress = value;
}
}
public int DescribeContents()
{
return 0;
}
public User(string Username, string Password, string Firstname, string MiddleInitial, string Lastname, string Suffix,
string address, string city, string state, string Zip, string Zip4, string Homephone, string Cellphone, string Workphone,
string NationalOrgn, string Country, string Company, string Section, string Department, string Usertype,
string Emailaddress)
{
this.mUsername = Username;
this.mPassword = Password;
this.mFirstname = Firstname;
this.mMiddleInitial = MiddleInitial;
this.mLastname = Lastname;
this.mSuffix = Suffix;
this.mAddress = Address;
this.mCity = City;
this.mState = State;
this.mZip = Zip;
this.mZip4 = Zip4;
this.mHomephone = Homephone;
this.mCellphone = Cellphone;
this.mWorkphone = Workphone;
this.mNationalOrgn = NationalOrgn;
this.mCountry = Country;
this.mCompany = Company;
this.mSection = Section;
this.mDepartment = Department;
this.mUsertype = Usertype;
this.mEmailaddress = Emailaddress;
}
public void WriteToParcel(Parcel dest, ParcelableWriteFlags flags)
{
dest.WriteString(this.Username);
dest.WriteString(this.Password);
dest.WriteString(this.Firstname);
dest.WriteString(this.MiddleInitial);
dest.WriteString(this.Lastname);
dest.WriteString(this.Suffix);
dest.WriteString(this.Address);
dest.WriteString(this.City);
dest.WriteString(this.State);
dest.WriteString(this.Zip);
dest.WriteString(this.Zip4);
dest.WriteString(this.Homephone);
dest.WriteString(this.Cellphone);
dest.WriteString(this.Workphone);
dest.WriteString(this.NationalOrgn);
dest.WriteString(this.Country);
dest.WriteString(this.Company);
dest.WriteString(this.Section);
dest.WriteString(this.Department);
dest.WriteString(this.Usertype);
dest.WriteString(this.Emailaddress);
}
}
class UserCreator : Object, IParcelableCreator
{
public Object CreateFromParcel(Parcel source)
{
return new User(source.ReadString(), source.ReadString(), source.ReadString(), source.ReadString(),
source.ReadString(), source.ReadString(), source.ReadString(), source.ReadString(), source.ReadString(),
source.ReadString(), source.ReadString(), source.ReadString(), source.ReadString(), source.ReadString(),
source.ReadString(), source.ReadString(), source.ReadString(), source.ReadString(), source.ReadString(),
source.ReadString(), source.ReadString());
}
public Object[] NewArray(int size)
{
return new Object[size];
}
}
}
I must be missing something ....
I think you got a bit of a naming issue here. Look at this part
public User(string Username, string Password, string Firstname, string MiddleInitial, string Lastname, string Suffix,
string address, string city, string state, string Zip, string Zip4, string Homephone, string Cellphone, string Workphone,
string NationalOrgn, string Country, string Company, string Section, string Department, string Usertype,
string Emailaddress)
{
this.mUsername = Username;
this.mPassword = Password;
this.mFirstname = Firstname;
this.mMiddleInitial = MiddleInitial;
this.mLastname = Lastname;
this.mSuffix = Suffix;
this.mAddress = Address;
this.mCity = City;
this.mState = State;
this.mZip = Zip;
this.mZip4 = Zip4;
this.mHomephone = Homephone;
this.mCellphone = Cellphone;
this.mWorkphone = Workphone;
this.mNationalOrgn = NationalOrgn;
this.mCountry = Country;
this.mCompany = Company;
this.mSection = Section;
this.mDepartment = Department;
this.mUsertype = Usertype;
this.mEmailaddress = Emailaddress;
}
Especially this:
this.mAddress = Address;
this.mCity = City;
this.mState = State;
The correct way would be:
this.mAddress = address;
this.mCity = city;
this.mState = state;
You are infact not using your parameters (these three at least)! This "error" is kinda mean, because your compiler is not complaining. That's because you actually are assigning your properties (=null) themselves and this is correct but certainly not intended here ;)!
Changing it to the above one should do the trick.

Check whether username is already in database

I am creating a help desk where one can create a new account. If the username is already in the database, you should get a message that tells you to take another username.
If the username is correct, the password must be provided with a hash before the data is entered in the database.
I have already searched for an answer via the internet but I don't find anything that works in my program.
//Declaratie private variabelen
private int _klantnummer;
private string _gebruikersnaam, _voornaam, _achternaam, _straatEnNummer, _postcode, _gemeente, _telefoonnummer, _email, _wachtwoord;
private bool _admin;
//Publieke eigenschappen
private int Klantnummer
{
get { return _klantnummer; }
set { _klantnummer = value; }
}
public string Gebruikersnaam
{
get { return _gebruikersnaam; }
set { _gebruikersnaam = value; }
}
public string Voornaam
{
get { return _voornaam; }
set { _voornaam = value; }
}
public string Achternaam
{
get { return _achternaam; }
set { _achternaam = value; }
}
public string StraatEnNummer
{
get { return _straatEnNummer; }
set { _straatEnNummer = value; }
}
public string Postcode
{
get { return _postcode; }
set { _postcode = value; }
}
public string Gemeente
{
get { return _gemeente; }
set { _gemeente = value; }
}
public string Telefoonnummer
{
get { return _telefoonnummer; }
set { _telefoonnummer = value; }
}
public string Email
{
get { return _email; }
set { _email = value; }
}
public string Wachtwoord
{
get { return _wachtwoord; }
set { _wachtwoord = value; }
}
public bool Admin
{
get { return _admin; }
set { _admin = value; }
}
//Default Constructor
public Klant()
{
Klantnummer = 0;
Gebruikersnaam = "";
Voornaam = "";
Achternaam = "";
StraatEnNummer = "";
Postcode = "";
Gemeente = "";
Telefoonnummer = "";
Email = "";
Wachtwoord = "";
Admin = false;
}
//Constructor met parameters
public Klant (string pGebruikersnaam, string pVoornaam, string pAchternaam, string pStraatEnNummer,
string pPostcode, string pGemeente, string pTelefoonnummer, string pEmail, string pWachtwoord,
bool pAdmin)
{
this.Gebruikersnaam = pGebruikersnaam;
this.Voornaam = pVoornaam;
this.Achternaam = pAchternaam;
this.StraatEnNummer = pStraatEnNummer;
this.Postcode = pPostcode;
this.Gemeente = pGemeente;
this.Telefoonnummer = pTelefoonnummer;
this.Email = pEmail;
this.Wachtwoord = pWachtwoord;
this.Admin = pAdmin;
}
//Constructor met parameters met klantnummer
public Klant(int pKlantnummer, string pGebruikersnaam, string pVoornaam, string pAchternaam, string pStraatEnNummer,
string pPostcode, string pGemeente, string pTelefoonnummer, string pEmail, string pWachtwoord,
bool pAdmin)
{
this.Klantnummer = pKlantnummer;
this.Gebruikersnaam = pGebruikersnaam;
this.Voornaam = pVoornaam;
this.Achternaam = pAchternaam;
this.StraatEnNummer = pStraatEnNummer;
this.Postcode = pPostcode;
this.Gemeente = pGemeente;
this.Telefoonnummer = pTelefoonnummer;
this.Email = pEmail;
this.Wachtwoord = pWachtwoord;
this.Admin = pAdmin;
}
What I usually do is make the username field unique in the database then use a try...catch on the call to the database. If it fails for a unique validation error I know the username was already used and respond to the user.

Exception of type 'Braintree.Exceptions.AuthenticationException' and Private key is seen as "PrivateKey"

Check out Controller
public class CheckoutsController : Controller
{
public IBraintreeConfiguration config = new BraintreeConfiguration();
public static readonly TransactionStatus[] transactionSuccessStatuses = {
TransactionStatus.AUTHORIZED,
TransactionStatus.AUTHORIZING,
TransactionStatus.SETTLED,
TransactionStatus.SETTLING,
TransactionStatus.SETTLEMENT_CONFIRMED,
TransactionStatus.SETTLEMENT_PENDING,
TransactionStatus.SUBMITTED_FOR_SETTLEMENT
};
public ActionResult New()
{
var gateway = config.GetGateway();
This is the line that is triggering the error ('Braintree.Exceptions.AuthenticationException')
var clientToken = gateway.ClientToken.generate();
ViewBag.ClientToken = clientToken;
return View();
}
public ActionResult Create()
{
var gateway = config.GetGateway();
Decimal amount;
try
{
amount = Convert.ToDecimal(Request["amount"]);
}
catch (FormatException e)
{
TempData["Flash"] = "Error: 81503: Amount is an invalid format.";
return RedirectToAction("New");
}
var nonce = Request["payment_method_nonce"];
var request = new TransactionRequest
{
Amount = amount,
PaymentMethodNonce = nonce,
Options = new TransactionOptionsRequest
{
SubmitForSettlement = true
}
};
Result<Transaction> result = gateway.Transaction.Sale(request);
if (result.IsSuccess())
{
Transaction transaction = result.Target;
return RedirectToAction("Show", new { id = transaction.Id });
}
else if (result.Transaction != null)
{
return RedirectToAction("Show", new { id = result.Transaction.Id });
}
else
{
string errorMessages = "";
foreach (ValidationError error in result.Errors.DeepAll())
{
errorMessages += "Error: " + (int)error.Code + " - " + error.Message + "\n";
}
TempData["Flash"] = errorMessages;
return RedirectToAction("New");
}
}
public ActionResult Show(String id)
{
var gateway = config.GetGateway();
Transaction transaction = gateway.Transaction.Find(id);
if (transactionSuccessStatuses.Contains(transaction.Status))
{
TempData["header"] = "Sweet Success!";
TempData["icon"] = "success";
TempData["message"] = "Your test transaction has been successfully processed. See the Braintree API response and try again.";
}
else
{
TempData["header"] = "Transaction Failed";
TempData["icon"] = "fail";
TempData["message"] = "Your test transaction has a status of " + transaction.Status + ". See the Braintree API response and try again.";
};
ViewBag.Transaction = transaction;
return View();
}
}
BrainTree Configuration
public class BraintreeConfiguration : IBraintreeConfiguration
{
public string Environment { get; set; }
public string MerchantId { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
private IBraintreeGateway BraintreeGateway { get; set; }
public IBraintreeGateway CreateGateway()
{
Environment = System.Environment.GetEnvironmentVariable("BraintreeEnvironment");
MerchantId = System.Environment.GetEnvironmentVariable("BraintreeMerchantId");
PublicKey = System.Environment.GetEnvironmentVariable("BraintreePublicKey");
PrivateKey = System.Environment.GetEnvironmentVariable("BraintreePrivateKey");
if (MerchantId == null || PublicKey == null || PrivateKey == null)
{
Environment = GetConfigurationSetting("BraintreeEnvironment");
MerchantId = GetConfigurationSetting("BraintreeMerchantId");
PublicKey = GetConfigurationSetting("BraintreePublicKey");
PrivateKey = GetConfigurationSetting("BraintreePrivateKey");
}
return new BraintreeGateway(Environment, MerchantId, PublicKey, PrivateKey);
}
public string GetConfigurationSetting(string setting)
{
//watch this
MerchantId = "**************";
PublicKey = "***************";
The merchant id and public Key are being assigned their correct values but the private Key is being assigned as "PrivateKey"
PrivateKey = "*************************";
return ConfigurationManager.AppSettings[setting];
}
public IBraintreeGateway GetGateway()
{
if (BraintreeGateway == null)
{
BraintreeGateway = CreateGateway();
}
return BraintreeGateway;
}
}

WebRequest 400 bad request to api

I am making webrequest to instagram api, and recieving 400 bad request, but i guess this is not something specific to instagram and is a generic error in my code.
here is my code."code" paramter in this request is obtained from previous request.Code breaks at "GetResponse" method
string clientID = "myclientid";
string clientsecret="myclientsecret";
string redirectURL = "http://localhost:64341/";
string webrequestUri = "https://api.instagram.com/oauth/
access_token? client_id=" + clientID + "&client_secret=
" + clientsecret + "&grant_type=authorization_code" + "&redirect_uri="redirectURL+"&code="
+Request.QueryString["code"].ToString();
WebRequest request = WebRequest.Create(webrequestUri);
request.Method = "POST";
WebResponse response = request.GetResponse();
C#/asp.net Working example:
namespace InstagramLogin.Code
{
public class InstagramAuth
{
private InstagramClient myApp = new InstagramClient();
public string genUserAutorizationUrl()
{
return String.Format(myApp.OAuthAutorizeURL, myApp.ClientId, myApp.RedirectUri);
}
public AuthUserApiToken getTokenId(string CODE)
{
//curl \-F 'client_id=CLIENT-ID' \
//-F 'client_secret=CLIENT-SECRET' \
//-F 'grant_type=authorization_code' \
//-F 'redirect_uri=YOUR-REDIRECT-URI' \
//-F 'code=CODE' \https://api.instagram.com/oauth/access_token
var wc = new WebClient();
var wcResponse = wc.UploadValues(myApp.AuthAccessTokenUrl,
new System.Collections.Specialized.NameValueCollection() {
{ "client_id", myApp.ClientId },
{ "client_secret", myApp.ClientSecret },
{ "grant_type", "authorization_code"},
{ "redirect_uri", myApp.RedirectUri},
{ "code", CODE}
});
var decodedResponse = wc.Encoding.GetString(wcResponse);
AuthUserApiToken UserApiToken = JsonConvert.DeserializeObject<AuthUserApiToken>(decodedResponse);
return UserApiToken;
}
}
}
your object:
namespace InstagramLogin.Code
{
public class InstagramClient
{
private const string ApiUriDefault = "https://api.instagram.com/v1/";
private const string OAuthUriDefault = "https://api.instagram.com/oauth/";
private const string RealTimeApiDefault = "https://api.instagram.com/v1/subscriptions/";
private const string OAuthAutorizeURLDefault = "https://api.instagram.com/oauth/authorize/?client_id={0}&redirect_uri={1}&response_type=code";
private const string AuthAccessTokenUrlDefault = "https://api.instagram.com/oauth/access_token";
private const string clientId = "clientid";
private const string clientSecretId = "clientsecretid";
private const string redirectUri = "http://localhost/InstagramLogin/InstaAuth.aspx";
private const string websiteUri = "http://localhost/InstagramLogin/InstaAuth.aspx";
public string ApiUri { get; set; }
public string OAuthUri { get; set; }
public string RealTimeApi { get; set; }
public string OAuthAutorizeURL { get { return OAuthAutorizeURLDefault; } }
public string ClientId { get { return clientId; } }
public string ClientSecret { get { return clientSecretId; } }
public string RedirectUri { get { return redirectUri; } }
public string AuthAccessTokenUrl { get { return AuthAccessTokenUrlDefault; } }
//removed props
}
}
instagram loged user:
namespace InstagramLogin.Code
{
public class SessionInstaAuthUser
{
public bool isInSession()
{
return HttpContext.Current.Session["AuthUserApiToken"] != null;
}
public AuthUserApiToken get()
{
if (isInSession())
{
return HttpContext.Current.Session["AuthUserApiToken"] as AuthUserApiToken;
}
return null;
}
public void set(AuthUserApiToken value)
{
HttpContext.Current.Session["AuthUserApiToken"] = value;
}
public void clear()
{
if (isInSession())
{
HttpContext.Current.Session["AuthUserApiToken"] = null;
}
}
}
}
markup:
<asp:Button ID="btnInstaAuth"
Text="Click here to get instagram auth"
runat="server" />
Code behind:
//objects
private InstagramClient InstagramApiCLient = new InstagramClient();
private InstagramAuth AuthManager = new InstagramAuth();
private SessionInstaAuthUser SesssionInstaUser = new SessionInstaAuthUser();
//click login with tests - user is logged (in session)
void btnInstaAuth_Click(Object sender,
EventArgs e)
{
btnGetInstaPosts.Visible = false;
if (SesssionInstaUser.isInSession())
{
SesssionInstaUser.clear();
Button clickedButton = (Button)sender;
clickedButton.Text = "Click here to get instagram auth";
btnInstaAuth.Visible = true;
}
else
{
Response.Redirect(AuthManager.genUserAutorizationUrl());
}
}
You can find what you need in this class InstagramAuth sorry if I did forgot to remove some of extra methods or properties, please strip it out.
This button can be used on all page, still don't forget to add on page load at the page set in instagram as login page, query string parse:
//here you read the token instagram generated and append it to the session, or get the error :)
if (!IsPostBack)
{
if (!SesssionInstaUser.isInSession())
{
if (Request.QueryString["code"] != null)
{
var token = AuthManager.getTokenId(Request.QueryString["code"]);
SesssionInstaUser.set(token);
//set login button to have option to log out
btnInstaAuth.Text = token.user.username + " leave instagtam oAuth";
Response.Redirect(Request.Url.ToString().Split('?')[0]);
}
else
if (Request.QueryString["error"] != null)
{
btnInstaAuth.Text = Request.QueryString["error_description"];
}
}
}
Sorry If I'd missed something, php curl in to c# is implemented in first class.
Update (I did forget something), insta user obj :)
namespace InstagramLogin.Code
{
public class UserLogged
{
public string id { get; set; }
public string username { get; set; }
public string full_name { get; set; }
public string profile_picture { get; set; }
}
public class AuthUserApiToken
{
public string access_token { get; set; }
public UserLogged user { get; set; }
}
}

WP8 HttpClient.PostAsync never returns result

I have a Windows Phone 8 app where I am calling await HttpClient.PostAsync and it never returns a result. It just sits there and hangs. If I run the exact same code from a console app, it returns the result almost immediately. All of the code doing the work resides in a portable class library. I would appreciate any help you may be able to give. All of the other issues I have found on this state to use await client.PostAsync, which I am already doing.
The code in my class library is as such:
public class Authenticator
{
private const string ApiBaseUrl = "http://api.fitbit.com";
private const string Callback = "http://myCallbackUrlHere";
private const string SignatureMethod = "HMAC-SHA1";
private const string OauthVersion = "1.0";
private const string ConsumerKey = "myConsumerKey";
private const string ConsumerSecret = "myConsumerSecret";
private const string RequestTokenUrl = "http://api.fitbit.com/oauth/request_token";
private const string AccessTokenUrl = "http://api.fitbit.com/oauth/access_token";
private const string AuthorizeUrl = "http://www.fitbit.com/oauth/authorize";
private string requestToken;
private string requestTokenSecret;
public string GetAuthUrlToken()
{
return GenerateAuthUrlToken().Result;
}
private async Task<string> GenerateAuthUrlToken()
{
var httpClient = new HttpClient { BaseAddress = new Uri(ApiBaseUrl) };
var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0);
var oauthTimestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString(CultureInfo.InvariantCulture);
var oauthNonce = DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture);
var authHeaderValue = string.Format(
"oauth_callback=\"{0}\",oauth_consumer_key=\"{1}\",oauth_nonce=\"{2}\"," +
"oauth_signature=\"{3}\",oauth_signature_method=\"{4}\"," +
"oauth_timestamp=\"{5}\",oauth_version=\"{6}\"",
Uri.EscapeDataString(Callback),
Uri.EscapeDataString(ConsumerKey),
Uri.EscapeDataString(oauthNonce),
Uri.EscapeDataString(this.CreateSignature(RequestTokenUrl, oauthNonce, oauthTimestamp, Callback)),
Uri.EscapeDataString(SignatureMethod),
Uri.EscapeDataString(oauthTimestamp),
Uri.EscapeDataString(OauthVersion));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"OAuth",
authHeaderValue);
var content = new StringContent(string.Empty);
var response = await httpClient.PostAsync(RequestTokenUrl, content);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Request Token Step Failed");
}
var responseContent = await response.Content.ReadAsStringAsync();
var responseItems = responseContent.Split(new[] { '&' });
this.requestToken = responseItems[0];
this.requestTokenSecret = responseItems[1];
var url = string.Format("{0}?{1}&display=touch", AuthorizeUrl, this.requestToken);
return url;
}
public string CreateSignature(string url, string nonce, string timestamp, string callback)
{
// code removed
return signatureString;
}
private static byte[] StringToAscii(string s)
{
// code removed
return retval;
}
}
I have a console app that calls this library and it works with no problem:
public class Program
{
public static void Main(string[] args)
{
var o = new Program();
o.LinkToFitbit();
}
public void LinkToFitbit()
{
var authenticator = new Authenticator();
// this works and returns the url immediately
var url = authenticator.GetAuthUrlToken();
// code removed
}
}
When I run from my WP8 app, it just hangs when it gets to this line in the library:
var response = await httpClient.PostAsync(RequestTokenUrl, content);
Here is my WP8 code:
public partial class FitbitConnector : PhoneApplicationPage
{
public FitbitConnector()
{
InitializeComponent();
this.AuthenticateUser();
}
private void AuthenticateUser()
{
var authenticator = new Authenticator();
var url = authenticator.GetAuthUrlToken();
// code removed
}
}
This line is blocking the UI thread:
public string GetAuthUrlToken()
{
return GenerateAuthUrlToken().Result;
}
The code after the await httpClient.PostAsync() needs to be executed in the UI thread, but it can't be executed because is is blocked.
So, replace this:
private void AuthenticateUser()
{
var authenticator = new Authenticator();
var url = authenticator.GetAuthUrlToken();
// code removed
}
With this:
private async void AuthenticateUser()
{
var authenticator = new Authenticator();
var url = await authenticator.GenerateAuthUrlToken();
// code removed
}
Notice I am using async and await. You will need to make GenerateAuthUrlToken() public. You can erase GetAuthUrlToken().
In few words, Task<T>.Result is not asynchronous.
Can you post CreateSignature and StringToAscii code ? I am stuck at basic oAuth.
I can get Request token but get "Invalid OAuth Signature" while performing a request for Access Token.
Nexus, here you go. I created an OauthHelper class that I use to build the pieces I need. Have a look below. I hope this helps.
public static class OauthHelper
{
public const string ConsumerKey = "MyKey";
public const string ConsumerSecret = "MySecret";
public const string UriScheme = "https";
public const string HostName = "api.somePlace.com";
public const string RequestPath = "/services/api/json/1.3.0";
public const string OauthSignatureMethod = "HMAC-SHA1";
public const string OauthVersion = "1.0";
public static string BuildRequestUri(Dictionary<string, string> requestParameters)
{
var url = GetNormalizedUrl(UriScheme, HostName, RequestPath);
var allParameters = new List<QueryParameter>(requestParameters.Select(entry => new QueryParameter(entry.Key, entry.Value)));
var normalizedParameters = NormalizeParameters(allParameters);
var requestUri = string.Format("{0}?{1}", url, normalizedParameters);
return requestUri;
}
public static AuthenticationHeaderValue CreateAuthorizationHeader(
string oauthToken,
string oauthNonce,
string oauthTimestamp,
string oauthSignature)
{
var normalizedUrl = GetNormalizedUrl(UriScheme, HostName, RequestPath);
return CreateAuthorizationHeader(oauthToken, oauthNonce, oauthTimestamp, oauthSignature, normalizedUrl);
}
public static AuthenticationHeaderValue CreateAuthorizationHeader(
string oauthToken,
string oauthNonce,
string oauthTimestamp,
string oauthSignature,
string realm)
{
if (string.IsNullOrWhiteSpace(oauthToken))
{
oauthToken = string.Empty;
}
if (string.IsNullOrWhiteSpace(oauthTimestamp))
{
throw new ArgumentNullException("oauthTimestamp");
}
if (string.IsNullOrWhiteSpace(oauthNonce))
{
throw new ArgumentNullException("oauthNonce");
}
if (string.IsNullOrWhiteSpace(oauthSignature))
{
throw new ArgumentNullException("oauthSignature");
}
var authHeaderValue = string.Format(
"realm=\"{0}\"," +
"oauth_consumer_key=\"{1}\"," +
"oauth_token=\"{2}\"," +
"oauth_nonce=\"{3}\"," +
"oauth_timestamp=\"{4}\"," +
"oauth_signature_method=\"{5}\"," +
"oauth_version=\"{6}\"," +
"oauth_signature=\"{7}\"",
realm,
Uri.EscapeDataString(ConsumerKey),
Uri.EscapeDataString(oauthToken),
Uri.EscapeDataString(oauthNonce),
Uri.EscapeDataString(oauthTimestamp),
Uri.EscapeDataString(OauthSignatureMethod),
Uri.EscapeDataString(OauthVersion),
Uri.EscapeDataString(oauthSignature));
var authHeader = new AuthenticationHeaderValue("OAuth", authHeaderValue);
return authHeader;
}
public static string CreateSignature(
string httpMethod,
string oauthToken,
string oauthTokenSecret,
string oauthTimestamp,
string oauthNonce,
Dictionary<string, string> requestParameters)
{
// get normalized url
var normalizedUrl = GetNormalizedUrl(UriScheme, HostName, RequestPath);
return CreateSignature(
httpMethod,
oauthToken,
oauthTokenSecret,
oauthTimestamp,
oauthNonce,
requestParameters,
normalizedUrl);
}
public static string CreateSignature(
string httpMethod,
string oauthToken,
string oauthTokenSecret,
string oauthTimestamp,
string oauthNonce,
Dictionary<string, string> requestParameters,
string realm)
{
if (string.IsNullOrWhiteSpace(httpMethod))
{
throw new ArgumentNullException("httpMethod");
}
if (string.IsNullOrWhiteSpace(oauthToken))
{
oauthToken = string.Empty;
}
if (string.IsNullOrWhiteSpace(oauthTokenSecret))
{
oauthTokenSecret = string.Empty;
}
if (string.IsNullOrWhiteSpace(oauthTimestamp))
{
throw new ArgumentNullException("oauthTimestamp");
}
if (string.IsNullOrWhiteSpace(oauthNonce))
{
throw new ArgumentNullException("oauthNonce");
}
var allParameters = new List<QueryParameter>
{
new QueryParameter("oauth_consumer_key", ConsumerKey),
new QueryParameter("oauth_token", oauthToken),
new QueryParameter("oauth_nonce", oauthNonce),
new QueryParameter("oauth_timestamp", oauthTimestamp),
new QueryParameter("oauth_signature_method", OauthSignatureMethod),
new QueryParameter("oauth_version", OauthVersion)
};
allParameters.AddRange(requestParameters.Select(entry => new QueryParameter(entry.Key, entry.Value)));
// sort params
allParameters.Sort(new QueryParameterComparer());
// concat all params
var normalizedRequestParameters = NormalizeParameters(allParameters);
// create base string
var signatureBase = string.Format(
"{0}&{1}&{2}",
UrlEncode(httpMethod.ToUpperInvariant()),
UrlEncode(realm),
UrlEncode(normalizedRequestParameters));
var signatureKey = string.Format(
"{0}&{1}",
UrlEncode(ConsumerSecret),
UrlEncode(oauthTokenSecret));
// hash the base string
var hmacsha1 = new HMACSHA1(StringToAscii(signatureKey));
var signatureString = Convert.ToBase64String(hmacsha1.ComputeHash(StringToAscii(signatureBase)));
return signatureString;
}
public static string GenerateNonce()
{
var ts = new TimeSpan(DateTime.Now.Ticks);
var ms = ts.TotalMilliseconds.ToString().Replace(".", string.Empty);
var nonce = ms;
return nonce;
}
public static string GenerateTimeStamp()
{
var timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0);
var timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString(CultureInfo.InvariantCulture);
return timestamp;
}
private static string GetNormalizedUrl(string uriScheme, string hostName, string requestPath)
{
var normalizedUrl = string.Format(
"{0}://{1}{2}",
uriScheme.ToLowerInvariant(),
hostName.ToLowerInvariant(),
requestPath);
return normalizedUrl;
}
private static string NormalizeParameters(IList<QueryParameter> parameters)
{
var result = new StringBuilder();
for (var i = 0; i < parameters.Count; i++)
{
var p = parameters[i];
result.AppendFormat("{0}={1}", p.Name, p.Value);
if (i < parameters.Count - 1)
{
result.Append("&");
}
}
return result.ToString();
}
private static byte[] StringToAscii(string s)
{
var retval = new byte[s.Length];
for (var ix = 0; ix < s.Length; ++ix)
{
var ch = s[ix];
if (ch <= 0x7f)
{
retval[ix] = (byte)ch;
}
else
{
retval[ix] = (byte)'?';
}
}
return retval;
}
private static string UrlEncode(string value)
{
const string Unreserved = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
var result = new StringBuilder();
foreach (char symbol in value)
{
if (Unreserved.IndexOf(symbol) != -1)
{
result.Append(symbol);
}
else
{
result.Append('%' + string.Format("{0:X2}", (int)symbol));
}
}
return result.ToString();
}
}
public class QueryParameter
{
public QueryParameter(string name, string value)
{
this.Name = name;
this.Value = value;
}
public string Name { get; private set; }
public string Value { get; private set; }
}
public class QueryParameterComparer : IComparer<QueryParameter>
{
public int Compare(QueryParameter x, QueryParameter y)
{
return x.Name == y.Name
? string.Compare(x.Value, y.Value)
: string.Compare(x.Name, y.Name);
}
}
Since you are using .Result or .Wait or await this will end up causing a deadlock in your code.
you can use ConfigureAwait(false) in async methods for preventing deadlock
like this:
var response = await httpClient.PostAsync(RequestTokenUrl, content).ConfigureAwait(false);
you can use ConfigureAwait(false) wherever possible for Don't Block Async Code .

Categories

Resources