Where can I find samples that show how to connect to the Magento REST API using C#?
I found was a php one which I could not figure out except a little.
Using a Dropbox OAuth sample I found on the net I tried to make it work for Magento:
private void button1_Click(object sender, RoutedEventArgs e)
{
var consumerKey = “xxxxxxxxxxxxx”;
var consumerSecret = “xxxxxxxxxxxxxxxx”;
var uri = new Uri("http://www.MagentoWebsite.com/oauth/token");
// Generate a signature
OAuthBase oAuth = new OAuthBase();
string nonce = oAuth.GenerateNonce();
string timeStamp = oAuth.GenerateTimeStamp();
string parameters;
string normalizedUrl;
string signature = oAuth.GenerateSignature(uri, consumerKey, consumerSecret,
String.Empty, String.Empty, “GET”, timeStamp, nonce, OAuthBase.SignatureTypes.HMACSHA1,
out normalizedUrl, out parameters);
signature = HttpUtility.UrlEncode(signature);
StringBuilder requestUri = new StringBuilder(uri.ToString());
requestUri.AppendFormat("?oauth_consumer_key={0}&", consumerKey);
requestUri.AppendFormat("oauth_nonce={0}&", nonce);
requestUri.AppendFormat("oauth_timestamp={0}&", timeStamp);
requestUri.AppendFormat("oauth_signature_method={0}&", “HMAC-SHA1");
requestUri.AppendFormat("oauth_version={0}&", “1.0");
requestUri.AppendFormat("oauth_signature={0}", signature);
var request = (HttpWebRequest)WebRequest.Create(new Uri(requestUri.ToString()));
request.Method = WebRequestMethods.Http.Get;
var response = request.GetResponse();
var queryString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var parts = queryString.Split(’&’);
var token = parts[1].Substring(parts[1].IndexOf(’=’) + 1);
var tokenSecret = parts[0].Substring(parts[0].IndexOf(’=’) + 1);
queryString = String.Format("oauth_token={0}", token);
var authorizeUrl = “http://www.MagentoWebsite.com/admin/oauth_authorize?”+queryString;
Process.Start(authorizeUrl);
}
Unfortunately this returns a BAD REQUEST response.
I recently started a project for a C# REST API client for Magento that might help you out:
https://github.com/nickvane/Magento-RestApi
It's not yet feature complete, but the oauth authentication is implemented.
The code uses restsharp which has support for oauth authentication.
I had the same question but couldn't find the answer hence I spent a day to make it work. I share my code here and I hope it will help other people in the feature.
use the following code in an aspx page to get oAuth access
protected void Page_Load(object sender, EventArgs e)
{
string oauth_token = Request.QueryString["oauth_token"];
string oauth_verifier = Request.QueryString["oauth_verifier"];
if (string.IsNullOrEmpty(oauth_token) || string.IsNullOrEmpty(oauth_verifier))
{
BeginAuthorization();
}
else
{
Authorize(oauth_token,oauth_verifier);
}
}
private void Authorize(string oauth_token, string oauth_verifier)
{
var uri = new Uri(MagentoServer + "/oauth/token");
string oauth_token_secret = (string)Session["oauth_token_secret"];
OAuthBase oAuth = new OAuthBase();
string nonce = oAuth.GenerateNonce();
string timeStamp = oAuth.GenerateTimeStamp();
string parameters;
string normalizedUrl;
string signature = oAuth.GenerateSignature(uri, ConsumerKey, ConsumerSecret,
oauth_token,oauth_token_secret, "GET", timeStamp, nonce, OAuthBase.SignatureTypes.PLAINTEXT,
out normalizedUrl, out parameters);
StringBuilder sb = new StringBuilder("OAuth ");
sb.AppendFormat("oauth_verifier=\"{0}\",", oauth_verifier);
sb.AppendFormat("oauth_token=\"{0}\",", oauth_token);
sb.AppendFormat("oauth_version=\"{0}\",", "1.0");
sb.AppendFormat("oauth_signature_method=\"{0}\",", "PLAINTEXT");
sb.AppendFormat("oauth_nonce=\"{0}\",", nonce);
sb.AppendFormat("oauth_timestamp=\"{0}\",", timeStamp);
sb.AppendFormat("oauth_consumer_key=\"{0}\",", ConsumerKey);
sb.AppendFormat("oauth_signature=\"{0}\"", signature);
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Headers[HttpRequestHeader.Authorization] = sb.ToString();
request.ContentType = "text/xml";
request.Accept = "text/xml";
request.KeepAlive = true;
request.Method = "POST";
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
string text = responseReader.ReadToEnd();
try
{
Dictionary<String, string> responseDic = GetDictionaryFromQueryString(text);
string token = responseDic.First(q => q.Key == "oauth_token").Value;
string secret = responseDic.First(q => q.Key == "oauth_token_secret").Value;
Configuration objConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
AppSettingsSection objAppsettings = (AppSettingsSection)objConfig.GetSection("appSettings");
//Edit
if (objAppsettings != null)
{
objAppsettings.Settings["Magento.Token"].Value = token;
objAppsettings.Settings["Magento.TokenSecret"].Value = secret;
objConfig.Save();
}
errorLabel.Text = "Done";
errorLabel.ForeColor = System.Drawing.Color.Green;
}
catch (Exception ex)
{
errorLabel.Text = "Exchanging token failed.<br>Response text = " + text + "<br>Exception = " + ex.Message;
}
}
}
catch (WebException ex)
{
var responseStream = ex.Response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
string resp = responseReader.ReadToEnd();
errorLabel.Text = resp;
}
}
private void BeginAuthorization()
{
string CallbackUrl = Server.UrlEncode(Request.Url.AbsoluteUri);
var uri = new Uri(MagentoServer + "/oauth/initiate?oauth_callback=" + CallbackUrl);
OAuthBase oAuth = new OAuthBase();
string nonce = oAuth.GenerateNonce();
string timeStamp = oAuth.GenerateTimeStamp();
string parameters;
string normalizedUrl;
string signature = oAuth.GenerateSignature(uri, ConsumerKey, ConsumerSecret,
String.Empty, String.Empty, "GET", timeStamp, nonce, OAuthBase.SignatureTypes.PLAINTEXT,
out normalizedUrl, out parameters);
StringBuilder sb = new StringBuilder("OAuth ");
sb.AppendFormat("oauth_callback=\"{0}\",", CallbackUrl);
sb.AppendFormat("oauth_version=\"{0}\",", "1.0");
sb.AppendFormat("oauth_signature_method=\"{0}\",", "PLAINTEXT");
sb.AppendFormat("oauth_nonce=\"{0}\",", nonce);
sb.AppendFormat("oauth_timestamp=\"{0}\",", timeStamp);
sb.AppendFormat("oauth_consumer_key=\"{0}\",", ConsumerKey);
sb.AppendFormat("oauth_signature=\"{0}\"", signature);
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Headers[HttpRequestHeader.Authorization] = sb.ToString();
request.ContentType = "text/xml";
request.Accept = "text/xml";
request.KeepAlive = true;
request.Method = "GET";
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
string text = responseReader.ReadToEnd();
try
{
Dictionary<String, string> dic = GetDictionaryFromQueryString(text);
string oauth_token = dic.First(q => q.Key == "oauth_token").Value;
string oauth_token_secret = dic.First(q => q.Key == "oauth_token_secret").Value;
Session["oauth_token_secret"] = oauth_token_secret;
string redirectUrl = MagentoServer + "/index.php/admin/oauth_authorize?oauth_token=" + oauth_token + "&oauth_verifier=" +
oauth_token_secret;
Response.Redirect(redirectUrl);
}
catch (Exception ex)
{
errorLabel.Text = "Parsing request token failed.<br>Response text = " + text + "<br>Exception = " + ex.Message;
}
}
}
catch (WebException ex)
{
var responseStream = ex.Response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
string resp = responseReader.ReadToEnd();
errorLabel.Text = resp;
}
}
private static Dictionary<string, string> GetDictionaryFromQueryString(string queryString)
{
string[] parts = queryString.Split('&');
Dictionary<String, string> dic = new Dictionary<string, string>();
foreach (var part in parts)
{
dic.Add(part.Split('=')[0], part.Split('=')[1]);
}
return dic;
}
#region Settings
string MagentoServer
{
get
{
return ConfigurationManager.AppSettings["Magento.Server"];
}
}
string ConsumerKey
{
get
{
return ConfigurationManager.AppSettings["Magento.ConsumerKey"];
}
}
string ConsumerSecret
{
get
{
return ConfigurationManager.AppSettings["Magento.ConsumerSecret"];
}
}
#endregion
}
add the following code in a class file
public class ApiClient
{
public ApiClient(string magentoServer, string consumerKey, string consumerSecret, string accessToken, string accessTokenSeccret)
{
MagentoServer = magentoServer;
ConsumerKey = consumerKey;
ConsumerSecret = consumerSecret;
AccessToken = accessToken;
AccessTokenSecret = accessTokenSeccret;
}
#region Request
HttpWebRequest CreateAuthorizedRequest(string url, string requestMethod,ApiFilter filter)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "?" + filter.ToString());
OAuthBase oAuth = new OAuthBase();
string nonce = oAuth.GenerateNonce();
string timeStamp = oAuth.GenerateTimeStamp();
string parameters;
string normalizedUrl;
string signature = oAuth.GenerateSignature(new Uri(url), ConsumerKey, ConsumerSecret,
AccessToken, AccessTokenSecret, requestMethod, timeStamp, nonce, OAuthBase.SignatureTypes.PLAINTEXT,
out normalizedUrl, out parameters);
StringBuilder sb = new StringBuilder("OAuth ");
sb.AppendFormat("oauth_token=\"{0}\",", AccessToken);
sb.AppendFormat("oauth_version=\"{0}\",", "1.0");
sb.AppendFormat("oauth_signature_method=\"{0}\",", "PLAINTEXT");
sb.AppendFormat("oauth_nonce=\"{0}\",", nonce);
sb.AppendFormat("oauth_timestamp=\"{0}\",", timeStamp);
sb.AppendFormat("oauth_consumer_key=\"{0}\",", ConsumerKey);
sb.AppendFormat("oauth_signature=\"{0}\"", signature);
request.Headers[HttpRequestHeader.Authorization] = sb.ToString();
request.Method = requestMethod;
//request.ContentType = "application/json";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";//application/json,
request.KeepAlive = true;
return request;
}
string FetchRequest(HttpWebRequest request)
{
try
{
string responseText = string.Empty;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader responseReader = new StreamReader(responseStream))
{
responseText = responseReader.ReadToEnd();
return responseText;
}
}
}
return responseText;
}
catch (WebException ex)
{
var responseStream = ex.Response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
string responseText = responseReader.ReadToEnd();
throw new MagentoApiException(responseText,ex.Status);
}
}
#endregion
#region Public properties
string MagentoServer { get; set; }
string ConsumerKey { get; set; }
string ConsumerSecret { get; set; }
string AccessToken { get; set; }
string AccessTokenSecret { get; set; }
#endregion
}
public class ApiFilter
{
public ApiFilter()
{
filterDescriptions = new List<FilterDescription>();
}
public int? Page { get; set; }
public int? Limit { get; set; }
public List<FilterDescription> filterDescriptions;
public const string Type = "rest";
public void AddFilter(string column, FilterType filterType, string value)
{
filterDescriptions.Add(new FilterDescription()
{
Column = column,
FilterType = filterType,
Value = value
});
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("type={0}", Type);
if (Page.HasValue)
sb.AppendFormat("&page={0}", Page.Value);
if (Limit.HasValue)
sb.AppendFormat("&limit={0}", Limit.Value);
int counter = 1;
foreach (var filter in filterDescriptions)
{
sb.AppendFormat("&filter[{0}][attribute]={1}&filter[{2}][{3}]={4}", counter, filter.Column, counter, filter.FilterType, filter.Value);
counter++;
}
return sb.ToString();
}
}
public class FilterDescription
{
public string Column { get; set; }
public FilterType FilterType { get; set; }
public string Value { get; set; }
}
public enum FilterType
{
/// <summary>
/// Not Equal To
/// </summary>
neq,
/// <summary>
/// equals any of
/// </summary>
#in,
/// <summary>
/// not equals any of
/// </summary>
nin,
/// <summary>
/// greater than
/// </summary>
gt,
/// <summary>
/// less than
/// </summary>
lt
}
public class MagentoApiException : Exception
{
public MagentoApiException(string responseText, WebExceptionStatus status)
{
ResponseText = responseText;
Status = status;
}
public string ResponseText { get; set; }
public WebExceptionStatus Status { get; set; }
}
also don't forget to add the https://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs to the project
it's ready to use. to read from api :
var request = CreateAuthorizedRequest(MagentoServer + "/api/rest/products", "get", new ApiFilter() {Page = 1 });
var responseText = FetchRequest(request);
Magento REST Api documantion can be found here
you can quickly create a client REST API using Spring.NET Social :
http://www.springframework.net/social/
Magento uses OAuth 1.0a authentication like Twitter. You can take a look to the Twitter implementation here:
http://www.springframework.net/social-twitter/
And the related documentation with step by step instructions:
http://www.springframework.net/social/refdoc/implementing.html
I'm not sure if this helps or not, but once I was able to get the oauth_token and oauth_token_secret from Magento (I used a PHP Magento sample to get it) I was able to query the REST API by putting everything in your requestUri into the header.
Your example helped me get most of the code correct, and just modified it a little (here's a little snippet):
StringBuilder sb = new StringBuilder("OAuth ");
sb.AppendFormat("oauth_version={0},", "1.0");
sb.AppendFormat("oauth_signature_method={0},", "HMAC-SHA1");
sb.AppendFormat("oauth_nonce={0},", nonce);
sb.AppendFormat("oauth_timestamp={0},", timeStamp);
sb.AppendFormat("oauth_consumer_key={0},", consumerKey);
sb.AppendFormat("oauth_token={0},", oauth_token);
sb.AppendFormat("oauth_signature={0}", sig);
Debug.WriteLine(sb.ToString());
var request = (HttpWebRequest)WebRequest.Create((resourceUrl));
request.Headers[HttpRequestHeader.Authorization] = sb.ToString();
request.ContentType = "text/xml";
request.Accept = "text/xml";
request.KeepAlive = true;
//request.Method = WebRequestMethods.Http.Get;
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Debug.WriteLine(response.StatusCode);
Debug.WriteLine(response.Server);
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(response.GetResponseStream());
Dts.Variables["User::XML_Response"].Value = xmlDoc.OuterXml.ToString();
}
Does that help?
Related
I have a 500 error when trying to consume a soap WS .
code below :
main function :
public void Main()
{
var action = "XXXXXX";
string result = SendSOAPRequest("http://XXXXXXXX:80/XXXX", action, new Dictionary<string, string>() , false);
}
sendrequest method :
public void Main()
{
var action = "XXXXXX";
string result = SendSOAPRequest("http://XXXXXXXX:80/XXXX", action, new Dictionary<string, string>() , false);
}
public static string SendSOAPRequest(string url, string action,Dictionary<string, string> parameters, bool useSOAP12 = false)
{
try{
XmlDocument soapEnvelopeXml = new XmlDocument();
var xmlStr = (useSOAP12)
? #"XXXXXX";
string parms = string.Join(string.Empty, parameters.Select(kv => String.Format("<{0}>{1}</{0}>", kv.Key, kv.Value)).ToArray());
var s = String.Format(xmlStr, action, new Uri(url).GetLeftPart(UriPartial.Authority) + "/", parms);
soapEnvelopeXml.LoadXml(s);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(url + "/" + action));
webRequest.Headers.Add("SOAPAction", url);
webRequest.Headers.Add("XXXXXX", "AG6YUTGV6");
webRequest.ContentType = (useSOAP12) ? "application/soap+xml;charset=\"utf-8\"" : "text/xml;charset=\"utf-8\"";
webRequest.Accept = (useSOAP12) ? "application/soap+xml" : "text/xml";
webRequest.Method = "GET";
string usernamePassword = "username" + ":" + "pass";
usernamePassword = Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword));
CredentialCache mycache = new CredentialCache();
webRequest.Credentials = mycache;
webRequest.Headers.Add("Authorization", "Basic " + usernamePassword);
using (WebResponse response = webRequest.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
XmlTextReader reader = new XmlTextReader(stream);
}
}
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
string result;
using (WebResponse response = webRequest.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
result = rd.ReadToEnd();
}
}
return result;
}
catch (WebException ex)
{
string message = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
}
return "";
}
I am struggling with the POST request for creating an article.
Can anybody please provide me an example value of the canonical request in C#?
The error I receive is signature issue:
{"errors":[{"code":"WRONG_SIGNATURE"}]}
From what I learnt a canonical request is build from:
Method = POST
URL = https://news-api.apple.com/channels/ChanelID/articles
Date = 2019-07-24T18:12:32Z
Content-Type = multipart/form-data
Body - Not fully understood
The Apple News API documentation says
If the request is a POST request and it includes an entity, include
the following:
The value of the Content-Type header
The full content of the entity - What is meant by this?
I want to post one test article from the json files provided in the apple's documentation.
This is the class generating the auth header:
public class Security
{
public static string AuthHeader(string method, string url, object content=null)
{
string formDataBoundary = String.Format("{0:N}", Guid.NewGuid());
var apiKeyId = Constants.AppleNewsKeyId;
var apiKeySecret = Constants.AppleNewsKeySecret;
if (string.IsNullOrEmpty(apiKeyId) || string.IsNullOrEmpty(apiKeySecret)) return string.Empty;
var encoding = new ASCIIEncoding();
var dt = DateTime.Now.ToString(Constants.DateFormat);
var canonicalRequest = string.Format("{0}{1}{2}{3}", method, url, dt, content);
var key = Convert.FromBase64String(apiKeySecret);
var hmac = new HMACSHA256(key);
var hashed = hmac.ComputeHash(encoding.GetBytes(canonicalRequest));
var signature = Convert.ToBase64String(hashed);
var authorizaton = string.Format(#"HHMAC; key={0}; signature={1}; date={2}", apiKeyId, signature, dt);
return authorizaton;
}
}
This is the constants class:
public static class Constants
{
public static readonly string ChannelId = "myID";
public static readonly string AppleNewsBaseUri = "https://news-api.apple.com";
public static readonly string DateFormat = "yyyy-MM-ddTHH:mm:ssK";
public static readonly string AppleNewsKeySecret = "myID";
public static readonly string AppleNewsKeyId = "myID";
}
And the action class which is missing code in order to have proper content instead of null passed to the AuthHeader method:
public class Action
{
public static string SendCommand(string action, string method)
{
var url = $"{Constants.AppleNewsBaseUri}{action}" + "/articles";
//string content = String.Format("{0}:{1}", "Content-Disposition", "form-data; filename=article.json; name=article.json;");
var authheader = Security.AuthHeader(method, url, null);
var request = WebRequest.Create(url);
request.PreAuthenticate = true;
request.Method = "POST";
request.Headers.Add("Authorization", authheader);
if (method.Equals("post", StringComparison.InvariantCultureIgnoreCase))
request.ContentType = "multipart/form-data;" ;
var output = string.Empty;
try
{
string filePath = Path.GetFullPath("article.json");
using (StreamReader r = new StreamReader(filePath))
{
string json = r.ReadToEnd();
dynamic jsonObj = JsonConvert.DeserializeObject(json);
ASCIIEncoding encoding = new ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(json);
request.ContentLength = bytes.Length;
Stream newStream = request.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
}
}
catch (Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
try
{
using (var response = request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
output = reader.ReadToEnd();
}
}
catch (WebException e)
{
using (var reader = new StreamReader(e.Response.GetResponseStream()))
{
output = reader.ReadToEnd();
}
}
return output;
}
public static string ReadChannel()
{
var action = $"/channels/{Constants.ChannelId}";
const string method = "POST";
return SendCommand(action, method);
}
}
I've written below C# code to login to JIRA Rest API:
var url = new Uri("http://localhost:8090/rest/auth/latest/session?os_username=tempusername&os_password=temppwd");
var request = WebRequest.Create(url) as HttpWebRequest;
if (null == request)
{
return "";
}
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = 200;
request.KeepAlive = false;
using (var response = request.GetResponse() as HttpWebResponse)
{
}
When I execute this, application just goes on running without returning any response. Please suggest if this is the right way of calling JIRA Login using REST API
For basic authentication you need to send in the username and password in a base64-encoding. Guidelines can be found in the API examples on atlassians developer page:
https://developer.atlassian.com/display/JIRADEV/JIRA+REST+API+Example+-+Basic+Authentication
, if you are doing it in C# you need to send the encoded data in the header in the following format:
"Authorization: Basic [ENCODED CREDENTIALS]"
Here is a simple example:
public enum JiraResource
{
project
}
protected string RunQuery(
JiraResource resource,
string argument = null,
string data = null,
string method = "GET")
{
string url = string.Format("{0}{1}/", m_BaseUrl, resource.ToString());
if (argument != null)
{
url = string.Format("{0}{1}/", url, argument);
}
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.ContentType = "application/json";
request.Method = method;
if (data != null)
{
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(data);
}
}
string base64Credentials = GetEncodedCredentials();
request.Headers.Add("Authorization", "Basic " + base64Credentials);
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
string result = string.Empty;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
return result;
}
private string GetEncodedCredentials()
{
string mergedCredentials = string.Format("{0}:{1}", m_Username, m_Password);
byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials);
return Convert.ToBase64String(byteCredentials);
}
(JiraResource is just an enum I use to decide which part of the API to use)
I hope this will help!
Here is a simpler solution which works as required:
var mergedCredentials = string.Format("{0}:{1}", username, password);
var byteCredentials = Encoding.UTF8.GetBytes(mergedCredentials);
var encodedCredentials = Convert.ToBase64String(byteCredentials);
using (WebClient webClient = new WebClient())
{
webClient.Headers.Set("Authorization", "Basic " + encodedCredentials);
return webClient.DownloadString(url);
}
If you don't want to encode your credentials in every request here is how to do it using cookies.
When requesting the cookie you don't need to add any authorization on the headers. This method will accept a JSON string with the user name and password and the URL. It will return the cookie values.
public async Task<JiraCookie> GetCookieAsync(string myJsonUserNamePassword, string JiraCookieEndpointUrl)
{
using (var client = new HttpClient())
{
var response = await client.PostAsync(
JiraCookieEndpointUrl,
new StringContent(myJsonUserNamePassword, Encoding.UTF8, "application/json"));
var json = response.Content.ReadAsStringAsync().Result;
var jiraCookie= JsonConvert.DeserializeObject<JiraCookie>(json);
return jArr;
}
}
public class JiraCookie
{
public Session session { get; set; }
}
public class Session
{
public string name { get; set; }
public string value { get; set; }
}
When I call it using url: http://[baseJiraUrl]/rest/auth/1/session it returns the following JSON response:
{
"session" : -{
"name" : JSESSIONID,
"value" : cookieValue
}
Keep in mind the URL above is valid in the version of JIRA I'm using and may vary depending on which version you're using. Read the JIRA API documentation for the correct URL for the version you are using. I'm using the following:
https://docs.atlassian.com/software/jira/docs/api/REST/7.6.1/#auth/1/session
Remember you'll have to store your cookie and use it on every subsequent request.
Check out this answer on how add cookies to your HttpClient request: How do I set a cookie on HttpClient's HttpRequestMessage.
Once you're done with the cookie (logging out) simply send a delete http request with the same URL as the post.
I tweaked the RunQuery code so that it will run today (Apr 2018). The encrypt/decrypt referenced below is from the following link (I converted it to an extension method and threw values into environment).
https://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp
I successfully execute the code from LinqPad - thus the Dump() command after RunQuery
private string _baseUrl = "https://xxxxxx.atlassian.net";
private string _username = "YourLogin";
void Main()
{
RunQuery(JiraResource.project).JsonToXml().Dump();
}
public enum JiraResource { project }
private const string restApiVersion = "/rest/api/2/";
protected string RunQuery( JiraResource resource, string argument = null, string data = null, string method = "GET")
{
string url = $"{_baseUrl}{restApiVersion}{resource}";
if (argument != null) url = $"{url}{argument}/";
var request = WebRequest.Create(url) as HttpWebRequest;
request.ContentType = "application/json";
request.Method = method;
if (data != null)
{
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(data);
}
}
string base64Credentials = GetEncodedCredentials();
request.Headers.Add("Authorization", "Basic " + base64Credentials);
var response = request.GetResponse() as HttpWebResponse;
string result = string.Empty;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
return result;
}
private string GetEncodedCredentials()
{
var encryptedPassword = Environment.GetEnvironmentVariable("PassEncrypted");
var encryptionSalt = Environment.GetEnvironmentVariable("PassSalt");
var password = encryptedPassword.Decrypt(encryptionSalt);
var mergedCredentials = $"{_username}:{password}";
var byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials);
return Convert.ToBase64String(byteCredentials);
}
public static class MyExtensions
{
public static XElement JsonToXml(this string jsonData, bool isAddingHeader = true)
{
var data = isAddingHeader
? "{\"record\":" + jsonData + "}"
: jsonData;
data = data // Complains if xml element name starts numeric
.Replace("16x16", "n16x16")
.Replace("24x24", "n24x24")
.Replace("32x32", "n32x32")
.Replace("48x48", "n48x48");
var result = JsonConvert.DeserializeXmlNode(data, "data");
var xmlResult = XElement.Parse(result.OuterXml);
return xmlResult;
}
}
For posting multipart content in Rest I use Tiny.RestClient.
var client = new TinyRestClient(new HttpClient(), "http://localhost:8090");
var strResult = await client.PostRequest("rest/auth/latest/session).
WithBasicAuthentication("username", "password")
ExecuteAsStringAsync();
static void Main(string[] args)
{
using (WebClient wc = new WebClient())
{
wc.Headers.Add("Authorization", "Basic " + GetEncodedCredentials());
string tasks = wc.DownloadString("yourjiraurl/search?jql=task=bug");
var taskdetails = JsonConvert.DeserializeObject<TaskDetails>(tasks);
}
}
static string GetEncodedCredentials()
{
string mergedCredentials = string.Format("{0}:{1}", "UserName", "Password");
byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials);
return Convert.ToBase64String(byteCredentials);
}
I am encountering a problem getting the access_token in client application using oauth.
The returned response has empty body though in API I can see the response is not empty.
tokenresponse = {
"access_token":"[ACCESSTOKENVALUE]",
"token_type":"bearer",
"expires_in":"1200",
"refresh_token":"[REFRESHTOKENVALUE]",
"scope":"[SCOPEVALUE]"
}
The method from API that returns the token http://api.sample.com/OAuth/Token:
public ActionResult Token()
{
OutgoingWebResponse response =
this.AuthorizationServer.HandleTokenRequest(this.Request);
string tokenresponse = string.Format("Token({0})", response!=null?response.Body:""));
return response.AsActionResult();
}
The client method that requests the token is:
public string GetAuthorizationToken(string code)
{
string Url = ServerPath + "OAuth/Token";
string redirect_uri_encode = UrlEncode(ClientPath);
string param = string.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code",code, ClientId, ClientSecret, redirect_uri_encode);
HttpWebRequest request = HttpWebRequest.Create(Url) as HttpWebRequest;
string result = null;
request.Method = "POST";
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = 10000;
request.Headers.Remove(HttpRequestHeader.Cookie);
var bs = Encoding.UTF8.GetBytes(param);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse response = request.GetResponse())
{
var sr = new StreamReader(response.GetResponseStream());
result = sr.ReadToEnd();
sr.Close();
}
if (!string.IsNullOrEmpty(result))
{
TokenData tokendata = JsonConvert.DeserializeObject<TokenData>(result);
return UpdateAuthorizotionFromToken(tokendata);
}
return null;
}
The result variable is empty.
Please let me know if you have any idea what could cause this. Initially I assumed is because of the cookies so I tried to remove them from request.
Thanks in advance.
Dear just create webclient using following code and you will get json info in tokeninfo.I used it and simply its working perfect.
WebClient client = new WebClient();
string postData = "client_id=" + ""
+ "&client_secret=" + ""
+ "&grant_type=password&username=" + "" //your username
+ "&password=" + "";//your password :)
string soundCloudTokenRes = "https://api.soundcloud.com/oauth2/token";
string tokenInfo = client.UploadString(soundCloudTokenRes, postData);
You can then use substring that contains only token from tokeninfo.
To upload tracks on sound cloud.
private void TestSoundCloudupload()
{
System.Net.ServicePointManager.Expect100Continue = false;
var request = WebRequest.Create("https://api.soundcloud.com/tracks") as HttpWebRequest;
//some default headers
request.Accept = "*/*";
request.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "en-US,en;q=0.8,ru;q=0.6");
//file array
var files = new UploadFile[] { new UploadFile(Server.MapPath("Downloads//0.mp3"), "track[asset_data]", "application/octet-stream") };
//other form data
var form = new NameValueCollection();
form.Add("track[title]", "Some title");
form.Add("track[sharing]", "public");
form.Add("oauth_token", "");
form.Add("format", "json");
form.Add("Filename", "0.mp3");
form.Add("Upload", "Submit Query");
try
{
using (var response = HttpUploadHelper.Upload(request, files, form))
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
Response.Write(reader.ReadToEnd());
}
}
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
}
Hi all i want to access azure tables entities from windows phone either using rest API or using Odata.
I have written a code but that this giving me NULL response. Every time i want to access a table entity i call GetEntity function. Below is the code that i am using.
Please if anybody know what wrong in this code or any help reply asap.
//////////// GetEntity Function.//////////
private void GetEntity(String tableName, String partitionKey, String rowKey)
{
String requestMethod = "GET";
String urlPath = String.Format("{0}(PartitionKey='{1}',RowKey='{2}')", tableName, partitionKey, rowKey);
String dateInRfc1123Format = DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
String stringToSign = String.Format(
"{0}\n\n\n{1}\n{2}",
requestMethod,
dateInRfc1123Format,
canonicalizedResource);
String authorizationHeader = CreateAuthorizationHeader(stringToSign);
HttpWebResponse response;
Uri uri = new Uri(AzureStorageConstants.TableEndPoint + urlPath);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = requestMethod;
request.Headers[HttpRequestHeader.ProxyAuthorization] = null;
request.Headers["Address"] = uri.ToString();
request.Headers["Method"] = requestMethod;
request.Headers["x-ms-date"]= DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
request.Headers["x-ms-version"]= "2011-08-18";
request.Headers["Authorization"] = authorizationHeader;
request.Headers["Accept-Charset"] = "UTF-8";
request.Headers["ContentType"] = "application/atom+xml,application/xml";
request.ContentType = "application/atom+xml,application/xml";
request.Headers["DataServiceVersion"] = "1.0;NetFx";
request.Headers["MaxDataServiceVersion"] = "1.0;NetFx";
using (response = GetResponse(request))
{
Stream dataStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataStream))
{
String responseFromServer = reader.ReadToEnd();
}
}
}
// GetResponse Function.
public HttpWebResponse GetResponse(HttpWebRequest request)
{
var dataReady = new AutoResetEvent(false);
HttpWebResponse response = null;
var callback = new AsyncCallback(delegate(IAsyncResult asynchronousResult)
{
response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
dataReady.Set();
});
request.BeginGetResponse(callback, request);
return response;
}
////// CreateAuthorization Function.///
private String CreateAuthorizationHeader(String canonicalizedString)
{
String signature = string.Empty;
using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(AzureStorageConstants.Key)))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
AzureStorageConstants.SharedKeyAuthorizationScheme,
AzureStorageConstants.Account,
signature);
return authorizationHeader;
}
////////AzureStorageConstants.
public static class AzureStorageConstants
{
private static String TableAccount = "datablobs";
private static String cloudEndPointFormat = "http://" + TableAccount + ".table.core.windows.net/";
private static String cloudKey = "Primary Access Key";// Here actual key is written.
private static string AzureStorage_SharedKeyAuthorizationScheme = "SharedKey";
public static String Account
{
get { return TableAccount; }
}
public static string SharedKeyAuthorizationScheme
{
get { return AzureStorage_SharedKeyAuthorizationScheme; }
}
public static string Key
{
get { return cloudKey; }
}
public static String TableEndPoint
{
get { return cloudEndPointFormat; }
}
}
for solution refer to below linked i have posted the solution there http://social.msdn.microsoft.com/Forums/en-US/windowsazureconnectivity/thread/84415c36-9475-4af0-9f52-c534f5681432
I checked you code and found the GetEntity() function does have some problem with regard to creating signature to access the Windows Azure Table Storage, so I hack together the following code which does work. You can just replace your GetEntity() and add two other function included in the code below to work signature process properly.
private string GetEntity(String tableName, String partitionKey, String rowKey)
{
string result = "";
String requestMethod = "GET";
String urlPath = String.Format("{0}(PartitionKey='{1}',RowKey='{2}')",tableName, partitionKey, rowKey);
DateTime now = DateTime.UtcNow;
HttpWebResponse response;
string uri = AzureStorageConstants.TableEndPoint + urlPath;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = requestMethod;
request.ContentLength = 0;
request.Headers.Add("x-ms-date", now.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2009-09-19");
request.ContentType = "application/atom+xml";
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
request.Headers.Add("MaxDataServiceVersion", "1.0;NetFx");
request.Headers.Add("If-Match", "*");
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("Authorization", AuthorizationHeader(requestMethod, now, request));
request.Accept = "application/atom+xml";
using (response = request.GetResponse() as HttpWebResponse)
{
Stream dataStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataStream))
{
result = reader.ReadToEnd();
}
}
return result;
}
public string AuthorizationHeader(string method, DateTime now, HttpWebRequest request)
{
string MessageSignature;
MessageSignature = String.Format("{0}\n\n{1}\n{2}\n{3}",
method,
"application/atom+xml",
now.ToString("R", System.Globalization.CultureInfo.InvariantCulture),
GetCanonicalizedResource(request.RequestUri, AzureStorageConstants.Account)
);
byte[] SignatureBytes = System.Text.Encoding.UTF8.GetBytes(MessageSignature);
System.Security.Cryptography.HMACSHA256 SHA256 = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(AzureStorageConstants.Key));
String AuthorizationHeader = "SharedKey " + AzureStorageConstants.Account + ":" + Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));
return AuthorizationHeader;
}
public string GetCanonicalizedResource(Uri address, string accountName)
{
StringBuilder str = new StringBuilder();
StringBuilder builder = new StringBuilder("/");
builder.Append(accountName);
builder.Append(address.AbsolutePath);
str.Append(builder.ToString());
NameValueCollection values2 = new NameValueCollection();
NameValueCollection values = HttpUtility.ParseQueryString(address.Query);
foreach (string str2 in values.Keys)
{
ArrayList list = new ArrayList(values.GetValues(str2));
list.Sort();
StringBuilder builder2 = new StringBuilder();
foreach (object obj2 in list)
{
if (builder2.Length > 0)
{
builder2.Append(",");
}
builder2.Append(obj2.ToString());
}
values2.Add((str2 == null) ? str2 : str2.ToLowerInvariant(), builder2.ToString());
}
ArrayList list2 = new ArrayList(values2.AllKeys);
list2.Sort();
foreach (string str3 in list2)
{
StringBuilder builder3 = new StringBuilder(string.Empty);
builder3.Append(str3);
builder3.Append(":");
builder3.Append(values2[str3]);
str.Append("\n");
str.Append(builder3.ToString());
}
return str.ToString();
}
To fix your Signature related problem, I took the code from Storage_REST_CS sample which has superb implementation of accessing Windows Azure (Blob, Table & Queue) Storage over REST interface.