So here is a bit of a brain-dump of my experiences...
To perform any API operation, you need to first instantiate a Session. In our case we have Partner access, so we need to create a XeroApiPartnerSession. The constructor requires an ITokenRepository (it also requires Certificates - but that's for another blog post!).
So since you can't create an instance of an Interface, you need to create your own class that implements ITokenRepository, and inside that class it's up to you to deal with the loading & saving of access tokens.
When I first saw this, I thought it was overkill - why couldn't I just pass in my access token?!? But I delved more into the API I learned that access tokens expire after 30 minutes - even with Partner access. This means you need to Renew your access token periodically. The good news is that if you implement an ITokenRepository, all this complexity is fully handed by the .NET API, so it's a pretty good design after all.
So onto creating a Token Repository... The ITokenRepository interface looks like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface ITokenRepository | |
{ | |
AccessToken GetAccessToken(); | |
RequestToken GetRequestToken(); | |
void SaveAccessToken(AccessToken accessToken); | |
void SaveRequestToken(RequestToken requestToken); | |
} |
So that meant I would need to store the values of the properties in the Set methods, and then re-create the classes in the Get methods. And that's what I did:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TokenRepository : ITokenRepository | |
{ | |
private readonly string _consumerKey = "YOUR_CONSUMER_KEY"; | |
public AccessToken GetAccessToken() | |
{ | |
var data = GetTokenData(); | |
return new AccessToken | |
{ | |
ConsumerKey = _consumerKey, | |
Token = data.Token, | |
TokenSecret = data.TokenSecret, | |
CreatedDateUtc = data.CreatedDateUtc, | |
ExpiresIn = data.ExpiresIn, | |
SessionHandle = data.SessionHandle, | |
SessionExpiresIn = data.SessionExpiresIn | |
}; | |
} | |
public RequestToken GetRequestToken() | |
{ | |
var data = GetTokenData(); | |
return new RequestToken | |
{ | |
ConsumerKey = _consumerKey, | |
Token = data.RequestToken, | |
TokenSecret = data.RequestTokenSecret | |
}; | |
} | |
public void SaveAccessToken(AccessToken accessToken) | |
{ | |
var data = GetTokenData(); | |
data.Token = accessToken.Token; | |
data.TokenSecret = accessToken.TokenSecret; | |
data.CreatedDateUtc = accessToken.CreatedDateUtc; | |
data.ExpiresIn = accessToken.ExpiresIn; | |
data.SessionExpiresIn = accessToken.SessionExpiresIn; | |
data.SessionHandle = accessToken.SessionHandle; | |
EditTokenData(data); | |
} | |
public void SaveRequestToken(RequestToken requestToken) | |
{ | |
var data = GetTokenData(); | |
data.RequestToken = requestToken.Token; | |
data.RequestTokenSecret = requestToken.TokenSecret; | |
EditTokenData(data); | |
} | |
private XeroTokenData GetTokenData() | |
{ | |
var dataJSON = ""; // Implement your own code here to retrieve token data from DB etc. | |
var serializer = new JavaScriptSerializer(); | |
return serializer.Deserialize<XeroTokenData>(dataJSON); | |
} | |
private void EditTokenData(XeroTokenData data) | |
{ | |
var data = new JavaScriptSerializer(); | |
var dataJSON = serializer.Serialize(settings); | |
// Implement your own code here to save dataJSON to your DB etc | |
} | |
[Serializable] | |
public class XeroTokenData | |
{ | |
public string Token { get; set; } | |
public string TokenSecret { get; set; } | |
public DateTime CreatedDateUtc { get; set; } | |
public string ExpiresIn { get; set; } | |
public string SessionExpiresIn { get; set; } | |
public string SessionHandle { get; set; } | |
public string RequestToken { get; set; } | |
public string RequestTokenSecret { get; set; } | |
} | |
} |
Anthony.