Related
Good day Guys,
I am trying to Use an SMS API. Everything looks fine from my end but the SMS is not delivering. If i use the URL directly on Browser, it executes.
Or is anything wrong with how i built the string?
Below is the code.
Please Note tht cbo.Title is a comobox, txtFirstname is a Textbox.
public void NewText()
{
string username = "something#gmail.com";
string password = "Password";
string urlStr;
string message=" Dear " + cbo_Title.Text + " " + txt_FirstName.Text + ", Your New Savings Account Number is " + Account_No + ".Welcome to AGENTKUNLE Global Services. Your Future is Our Priority ";
string sender = "AGENTKUNLE";
string recipient=txt_Phone.Text;
urlStr = "https://portal.nigeriabulksms.com/api/?username="+username+"+password="+password+"+sender="+sender+"+message="+message+"+ mobiles="+recipient;
Uri success = new Uri(urlStr);
}
private string SendSms(string apiUrl)
{
var targetUri = new Uri(apiUrl);
var webRequest = (HttpWebRequest) WebRequest.Create(targetUri);
webRequest.Method = WebRequestMethods.Http.Get;
try
{
string webResponse;
using (var getresponse = (HttpWebResponse) webRequest.GetResponse())
{
var stream = getresponse.GetResponseStream();
if (stream != null)
using (var reader = new StreamReader(stream))
{
webResponse = reader.ReadToEnd();
reader.Close();
}
else
webResponse = null;
getresponse.Close();
}
if (!string.IsNullOrEmpty(webResponse?.Trim()))
return webResponse.Trim();
}
catch (WebException ex)
{
ErrorHelper.Log(ex);
}
catch (Exception ex)
{
ErrorHelper.Log(ex);
}
finally
{
webRequest.Abort();
}
return null;
}
You never make a request.
The Uri object is just a container for the uri (see Microsoft Docs).
Check out the HttpClient class if you want to send a request.
I am not able to get the friends list from the facebook graph api.
it is throwing exception the Bad request.
https://graph.facebook.com/me/friends?access_token="accessTokenString";
here is my code
public IDictionary<string, string> GetUserData(string accessCode, string redirectURI)
{
string token = GetHTML(Facebook_GraphAPI_Token + "client_id=" + AppID + "&redirect_uri=" + HttpUtility.HtmlEncode(redirectURI) + "%3F__provider__%3Dfacebook" + "&client_secret=" + AppSecret + "&code=" + accessCode);
if (token == null || token == "")
{
return null;
}
string friendsData = Web.GetHTML(Facebook_GraphAPI_Friends + "fields=id,first_name,last_name,name,email,username,gender,link,bio,birthday,friendlists,friends&access_token=" + token.Substring("access_token=", "&"));
//string substringToken=token.Substring("access_token=", "&");
//string friendsData = Web.GetHTML(Facebook_GraphAPI_Friends + substringToken);
return friendsData ;
}
public static string GetHTML(string URL)
{
string connectionString = URL;
try
{
System.Net.HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(connectionString);
myRequest.Credentials = CredentialCache.DefaultCredentials;
//// Get the response
WebResponse webResponse = myRequest.GetResponse();
Stream respStream = webResponse.GetResponseStream();
////
StreamReader ioStream = new StreamReader(respStream);
string pageContent = ioStream.ReadToEnd();
//// Close streams
ioStream.Close();
respStream.Close();
return pageContent;
}
catch (Exception)
{
}
return null;
}
I have found wrong fields in friends request api
friendlists,friends please remove these fields
Correct End Point
https://graph.facebook.com/me/friends?fields=id,first_name,last_name,name,email,username,gender,link,bio,birthday&access_token={your facebook access token}
So I'm trying to put together some very simple and elegant code samples to help people use my API. The latest language I'm tackling is C#.
I think the IETF OAuth2.0 standard I read implies the HTTP request Content-Type must be "application/x-www-form-urlencoded". The Django API server I have, currently seems to only support this Content-Type (for the OAuth resource). The other languages POST content this way by default!
After extensive research and several experiments I am wondering if I have missed something fundamental. Surely there would be a helpful library OR technique to create the ...urlencoded string OR at least someone else must have run into this???
I will outline some of the best solution I have so far bellow, but it just seems wrong.
Also from a bunch of internet browsing I figured I would use the HttpClient library. I like the fact that it uses the async model, which perhaps will be more useful for any developers using WPF or XAML or Windows 8 apps. It also works well for Consoles and Forms.
I use the Newtonsoft Json.Net library for serialization. First of all I create a POCO of the authorization strings. Then I serialize it to JSON, then to key/value pairs, then iterate through the key/value pairs catenating with the required '=' and '&' chars, then UTF-8, then escape the spaces etc.
//Setup HTTP request
HttpClient httpRequest = new HttpClient();
httpRequest.DefaultRequestHeaders.Add("Accept", "application/json");
string urlBase = "https://__secret__/api/v1/";
HttpResponseMessage msg = new HttpResponseMessage();
//POST to oauth to get token (must be sent as "application/x-www-form-urlencoded")
OAuthConfig oAuthCredentials = new OAuthConfig { client_id = client_id, client_secret = secret, username = "__secret__", password = "__secret__", grant_type = "__secret__" };
string jsonString = JsonConvert.SerializeObject(oAuthCredentials); //convert to JSON
Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString); //convert to key/value pairs
string urlEncodedData = ConvertToFormUrlEncodedFormat(values);
HttpContent payload = new StringContent(urlEncodedData, Encoding.UTF8, "application/x-www-form-urlencoded");
msg = httpRequest.PostAsync(urlBase + "oauth/access_token/", payload).Result;
string responseBodyAsText = msg.Content.ReadAsStringAsync().Result;
Console.WriteLine(responseBodyAsText);
Other options I could think of were...
Reflection, however digging into reflection in a code sample seems a bit manic.
It turns out that other than the OAuth setup, the rest of the API supports JSON type POSTs. So I guess I could write a function to walk through the oAuthConfig model and catenate a string, since that POCO model is unlikely to change and is the only model which requires urlEncoding that I can anticipate. That would save us from the slightly confusing use of the Dictionary. The use of the dictionary and then iterating is more generic, however perhaps a bit OTT.
I figure most of the time people will be using JSON, so showing how that might happen is useful.
In general it seems quite hard to serialize a POCO model to a string and/or to a urlEncoded string.
Questions
does OAuth mandate urlencoded, could you convert server-side?
is HttpClient the best choice, does async matter?
is there a better simpler way to serialize a POCO to ...form-urlencoded?
Thanks for any useful comments you may have.
var model = new LoginModel { Username = "patient#gmail.com", Password = "123456", DeviceId = "123456789", RoleId = 1 };
url.Append("/Login");
string data = JsonConvert.SerializeObject(model);// "{\"username\":\"dscdemo0#gmail.com\",\"password\":\"vipin123\"}";
NameValueCollection inputs = new NameValueCollection();
inputs.Add("json", data);
WebClient client = new WebClient();
var reply = client.UploadValues(url.ToString(), inputs);
string temp = Encoding.ASCII.GetString(reply);
var result = JsonConvert.DeserializeObject<MessageTemplateModel>
(temp);
Api Call
public async Task<IHttpActionResult> Login(HttpRequestMessage request)//(LoginModel modelN)
{
try
{
var form = request.Content.ReadAsFormDataAsync().Result;
var modelN = JsonConvert.DeserializeObject<LoginModel>(form["json"].ToString());
// token = JsonConvert.DeserializeObject<string>(form["token"].ToString());
bool istoken = _appdevice.GettokenID(modelN.DeviceId);
if (!istoken)
{
statuscode = 0;
message = ErrorMessage.TockenNotvalid;
goto invalidtoken;
}
User model = new User();
// var session = HttpContext.Current.Session;
// session.Add("UserRole", GetProfileId.UserRole);
var user = await _userManager.FindAsync(modelN.Username, modelN.Password);}}
i am able to call url-encoder request from device and web app.
//I disclaimer everything and note that I haven't re-checked if this posted code works.
using System;
using System.Text;
using System.Collections.Generic;
using Newtonsoft.Json; //install with Nuget package installer- "json.Net"
using System.Net.Http; //install with Nuget package installer- "...Web API client libraries"
using System.Net;
using System.IO;
using System.Runtime.Serialization.Json; //security risk till certificate fixed
namespace CSharpDemoCodeConsole
{
class Program
{
const string api_key = "your_api_key"; //set your api_key here
const string user_auth = "your_username" + ":" + "your_password"; // set your user credentials here
const string urlBase = "https://#SECRET.com#/api/v1";
static void Main(string[] args)
{
Console.WriteLine("Making call to webserver asynchronously");
MakeCallAsynchronously();
Console.WriteLine("**************************************");
Console.WriteLine("Making call to webserver synchronously");
MakeCallSynchronously();
Console.WriteLine("**************************************");
Console.WriteLine("Making call to webserver synchronously without Newtonsoft serialization");
MakeCallSynchronouslyWithoutNewtonSoft();
Console.WriteLine("Press spacebar to close the application");
Console.ReadKey();
}
private static void MakeCallAsynchronously()
{
//Always accept untrusted certificates - don't use in production
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
//Setup request
string authorizeString = Convert.ToBase64String(Encoding.ASCII.GetBytes(user_auth));
HttpClient httpRequest = new HttpClient();
httpRequest.DefaultRequestHeaders.Add("Authorization", "Basic " + authorizeString);
httpRequest.DefaultRequestHeaders.Add("Accept", "application/json");
//GET from places resource
try
{
var requestTask = httpRequest.GetAsync(urlBase + "places/" + "?api_key=" + api_key,
System.Net.Http.HttpCompletionOption.ResponseContentRead);
//Update UI while waiting for task to complete
while (requestTask.Status != System.Threading.Tasks.TaskStatus.RanToCompletion)
{
Console.Write(".");
System.Threading.Thread.Sleep(30);
}
if (requestTask.Result.StatusCode != HttpStatusCode.OK)
{
Console.WriteLine("Unexpected response from server: {0}", requestTask.Result);
return;
}
var places = JsonConvert.DeserializeObject<Page<Place>>(requestTask.Result.Content.ReadAsStringAsync().Result);
Console.WriteLine("GET places response " + requestTask.Result.Content.ReadAsStringAsync().Result);
}
catch (WebException ex)
{
Console.WriteLine(ex.ToString());
return;
}
//POST to places resource
try
{
string jsonString = JsonConvert.SerializeObject(new Place { name = "test place", latitude = 0, longitude = 0 });
HttpContent payload = new StringContent(jsonString, Encoding.UTF8, "application/json");
var requestTask = httpRequest.PostAsync(urlBase + "places/" + "?api_key=" + api_key, payload);
//Update UI while waiting for task to complete
while (requestTask.Status != System.Threading.Tasks.TaskStatus.RanToCompletion)
{
Console.Write(".");
System.Threading.Thread.Sleep(30);
}
if (requestTask.Result.StatusCode != HttpStatusCode.Created)
{
Console.WriteLine("Unexpected response from server: {0}", requestTask.Result);
return;
}
Console.WriteLine("POST places response " + requestTask.Result.Content.ReadAsStringAsync().Result);
}
catch (WebException ex)
{
Console.WriteLine(ex.ToString());
return;
}
}
private static void MakeCallSynchronously()
{
//Always accept untrusted certificates - don't use in production
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
//Setup Request
string authorizeString = Convert.ToBase64String(Encoding.ASCII.GetBytes(user_auth));
var client = new WebClient();
client.Headers.Add("Authorization", "Basic " + authorizeString);
client.Headers.Add("Accept", "application/json");
//GET from places resource
try
{
var responseStream = client.OpenRead(urlBase + "places/" + "?api_key=" + api_key);
var response = (new StreamReader(responseStream).ReadToEnd());
var places = JsonConvert.DeserializeObject<Page<Place>>(response);
Console.WriteLine("GET places response " + response);
}
catch (WebException ex)
{
Console.WriteLine(ex.ToString());
}
//POST to places resource
try
{
client.Headers.Add("Accept", "application/json");
client.Headers.Add("Content-Type", "application/json");
string jsonString = JsonConvert.SerializeObject(new Place { name = "test place", latitude = 0, longitude = 0 });
client.Encoding = System.Text.Encoding.UTF8;
string response = client.UploadString(urlBase + "places/" + "?api_key=" + api_key, jsonString);
Console.WriteLine("POST places response " + response);
}
catch (WebException ex)
{
Console.WriteLine(ex.ToString());
return;
}
}
private static void MakeCallSynchronouslyWithoutNewtonSoft()
{
//Always accept untrusted certificates - don't use in production
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
//Setup Request
string authorizeString = Convert.ToBase64String(Encoding.ASCII.GetBytes(user_auth));
var client = new WebClient();
client.Headers.Add("Authorization", "Basic " + authorizeString);
client.Headers.Add("Accept", "application/json");
//GET from places resource
try
{
var responseStream = client.OpenRead(urlBase + "places/" + "?api_key=" + api_key);
MemoryStream ms = new MemoryStream();
responseStream.CopyTo(ms);
ms.Position = 0;
var placesDeserializer = new DataContractJsonSerializer(typeof(Page<Place>));
var places = (Page<Place>)placesDeserializer.ReadObject(ms);
ms.Position = 0;
string response = (new StreamReader(ms).ReadToEnd());
ms.Close();
Console.WriteLine("GET places response " + response);
}
catch (WebException ex)
{
Console.WriteLine(ex.ToString());
return;
}
//POST to places resource
try
{
client.Headers.Add("Accept", "application/json");
client.Headers.Add("Content-Type", "application/json");
DataContractJsonSerializer placesSerializer = new DataContractJsonSerializer(typeof(Place));
Place place = new Place { name = "test place", latitude = 0, longitude = 0 };
MemoryStream ms = new MemoryStream();
placesSerializer.WriteObject(ms, place);
byte[] json = ms.ToArray();
ms.Close();
string jsonString = Encoding.UTF8.GetString(json, 0, json.Length);
client.Encoding = System.Text.Encoding.UTF8;
string response = client.UploadString(urlBase + "places/" + "?api_key=" + api_key, jsonString);
Console.WriteLine("POST places response " + response);
}
catch (WebException ex)
{
Console.WriteLine(ex.ToString());
return;
}
}
}
public class Place
{
[JsonProperty("url")]
public string url { get; set; }
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("latitude")]
public float latitude { get; set; }
[JsonProperty("longitude")]
public float longitude { get; set; }
}
public class Page<T>
{
[JsonProperty("count")]
public int count { get; set; }
[JsonProperty("next")]
public string next { get; set; }
[JsonProperty("previous")]
public string previous { get; set; }
[JsonProperty("results")]
public List<T> results { get; set; }
}
}
How to POST attachment to JIRA using JIRA REST API and HttpWebRequest in C#?
From the documentation under /rest/api/2/issue/{issueIdOrKey}/attachments:
POST
Add one or more attachments to an issue.
This resource expects a multipart post. The media-type multipart/form-data is defined in RFC 1867. Most client libraries have classes that make dealing with multipart posts simple. For instance, in Java the Apache HTTP Components library provides a MultiPartEntity that makes it simple to submit a multipart POST.
In order to protect against XSRF attacks, because this method accepts multipart/form-data, it has XSRF protection on it. This means you must submit a header of X-Atlassian-Token: nocheck with the request, otherwise it will be blocked.
The name of the multipart/form-data parameter that contains attachments must be "file"
A simple example to upload a file called "myfile.txt" to issue REST-123:
curl -D- -u admin:admin -X POST -H "X-Atlassian-Token: nocheck" -F "file=#myfile.txt" http://myhost.test/rest/api/2/issue/TEST-123/attachments
I have
foreach (JIRAAttachments attachm in attachments.attachments)
{
request = HttpWebRequest.Create(
logInformation.GetUri() + "/rest/api/2/issue/" + key + "/attachments"
) as HttpWebRequest;
request.Headers.Add("Authorization: Basic " + logInformation.GetEncodeAuthentication());
request.Method = "POST";
request.ContentType = "multipart/form-data";
request.Headers.Add("X-Atlassian-Token: nocheck file=#" + Path.GetFullPath(#"..\Attachments\" + attachm.filename));
request.KeepAlive = true;
request.Proxy = wp;
response = (HttpWebResponse)request.GetResponse();
Stream s = response.GetResponseStream();
FileStream fs = new FileStream(Path.GetFullPath(#"..\Attachments\" + attachm.filename), FileMode.Open);
byte[] write = new byte[256];
int count = fs.Read(write, 0, write.Length);
while (count > 0)
{
s.Write(write, 0, count);
count = fs.Read(write, 0, write.Length);
}
fs.Close();
s.Close();
response.Close();
}
but it returns a 404 error...
solved your problem:
var boundary = string.Format("----------{0:N}", Guid.NewGuid());
System.IO.MemoryStream content = new MemoryStream();
var writer = new StreamWriter(content);
foreach (var att in attachments)
{
writer.WriteLine("--{0}", boundary);
writer.WriteLine("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"", "file", Path.GetFileName(att["filename"]));
writer.WriteLine("Content-Type: {0}", att.ContentType);
writer.WriteLine();
writer.Flush();
att.Stream.CopyTo(content);
writer.WriteLine();
}
writer.WriteLine("--" + boundary + "--");
writer.Flush();
content.Seek(0, SeekOrigin.Begin);
HttpWebRequest oRequest = null;
oRequest = (HttpWebRequest)HttpWebRequest.Create(string.Format(RestBaseURI + "issue/{0}/attachments", item.Key));
oRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
oRequest.Method = "POST";
oRequest.Headers.Add("Authorization", AuthData);
oRequest.Headers.Add("X-Atlassian-Token", "nocheck");
oRequest.UseDefaultCredentials = true;
oRequest.KeepAlive = true;
oRequest.ContentLength = content.Length;
using (var oStream = oRequest.GetRequestStream())
{
content.CopyTo(oStream);
}
using (var oResponse = (HttpWebResponse)oRequest.GetResponse())
{
using (var reader = new StreamReader(oResponse.GetResponseStream()))
{
var responseData = reader.ReadToEnd();
var data = JObject.Parse(responseData);
}
}
PS: thanks2mod to delete my previous post! nice ...
There was a couple of mistakes in the OP's code.
With the snippet provided by #mabu and the code I found on http://www.briangrinstead.com/blog/multipart-form-post-in-c, here's a *functional** Code Block to Upload attachment to Jira.
public bool AddAttachments(string issueKey, IEnumerable<string> filePaths)
{
string restUrl = Jira.FormatRestUrl(m_JiraId, true);
string issueLinkUrl = String.Format("{0}/issue/{1}/attachments", restUrl, issueKey);
var filesToUpload = new List<FileInfo>();
foreach (var filePath in filePaths)
{
if (!File.Exists(filePath))
{
Jira.LogError("File '{0}' doesn't exist", filePath);
return false;
}
var file = new FileInfo(filePath);
if (file.Length > 10485760) // TODO Get Actual Limit
{
Jira.LogError("Attachment too large");
return false;
}
filesToUpload.Add(file);
}
if (filesToUpload.Count <= 0)
{
Jira.LogWarning("No file to Upload");
return false;
}
return PostMultiPart(issueLinkUrl, filesToUpload);
}
private Boolean PostMultiPart(string restUrl, IEnumerable<FileInfo> filePaths)
{
HttpWebResponse response = null;
HttpWebRequest request = null;
try
{
var boundary = string.Format("----------{0:N}", Guid.NewGuid());
var content = new MemoryStream();
var writer = new StreamWriter(content);
foreach (var filePath in filePaths)
{
var fs = new FileStream(filePath.FullName, FileMode.Open, FileAccess.Read);
var data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
fs.Close();
writer.WriteLine("--{0}", boundary);
writer.WriteLine("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"", filePath.Name);
writer.WriteLine("Content-Type: application/octet-stream");
writer.WriteLine();
writer.Flush();
content.Write(data, 0, data.Length);
writer.WriteLine();
}
writer.WriteLine("--" + boundary + "--");
writer.Flush();
content.Seek(0, SeekOrigin.Begin);
request = WebRequest.Create(restUrl) as HttpWebRequest;
if (request == null)
{
Jira.LogError("Unable to create REST query: {0}", restUrl);
return false;
}
request.Method = "POST";
request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
request.Accept = "application/json";
request.Headers.Add("Authorization", "Basic " + m_EncodedCredential);
request.Headers.Add("X-Atlassian-Token", "nocheck");
request.ContentLength = content.Length;
using (Stream requestStream = request.GetRequestStream())
{
content.WriteTo(requestStream);
requestStream.Close();
}
using (response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
{
var reader = new StreamReader(response.GetResponseStream());
Jira.LogError("The server returned '{0}'\n{1}", response.StatusCode, reader.ReadToEnd());
return false;
}
return true;
}
}
catch (WebException wex)
{
if (wex.Response != null)
{
using (var errorResponse = (HttpWebResponse)wex.Response)
{
var reader = new StreamReader(errorResponse.GetResponseStream());
Jira.LogError("The server returned '{0}'\n{1}).", errorResponse.StatusCode, reader.ReadToEnd());
}
}
if (request != null)
{
request.Abort();
}
return false;
}
finally
{
if (response != null)
{
response.Close();
}
}
}
I really didn't want to deal with all that boundary stuff, so here's my shot at it. This works against Confluence whose API looks identical to Jira.
Thanks to Michael Teper at ASP.NET WebApi: how to perform a multipart post with file upload using WebApi HttpClient
and Jeff Caron (above).
var contents = "some long HTML that I wanted to upload";
var fileName = "Some fancy file name.html";
using (var client = new HttpClient())
{
var uri = new Uri(URL);
client.BaseAddress = new Uri(URL);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = authorization;
client.DefaultRequestHeaders.Add("X-Atlassian-Token", "nocheck");
var uriPath = String.Format(AttachmentPath, pageId);
var content = new MultipartFormDataContent();
var fileContent = new StringContent(contents);
// also tested to work:
// var fileContent = new ByteArrayContent(Encoding.UTF8.GetBytes(contents));
content.Add(fileContent, "file", fileName);
var response = await client.PostAsync(uriPath, content);
if (response.IsSuccessStatusCode)
{
return TaskResult.Success(null, response.ReasonPhrase);
}
else
{
return TaskResult.Failure("Service responded with Status Code: " + response.StatusCode + Environment.NewLine + "Reason Phrase: " + response.ReasonPhrase);
}
}
You're also able to do with Restsharp as follow
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Jira
using RestSharp;
using RestSharp.Authenticators;
namespace Jira
{
class Program
{
static void Main(string[] args)
{
var client = new RestClient("http://{URL}/rest/api/2");
var request = new RestRequest("issue/", Method.POST);
client.Authenticator = new HttpBasicAuthenticator("user", "pass");
var issue = new Issue
{
fields =
new Fields
{
description = "Issue Description",
summary = "Issue Summary",
project = new Project { key = "KEY" },
issuetype = new IssueType { name = "ISSUE_TYPE_NAME" }
}
};
request.AddJsonBody(issue);
var res = client.Execute<Issue>(request);
if (res.StatusCode == HttpStatusCode.Created)
{
Console.WriteLine("Issue: {0} successfully created", res.Data.key);
#region Attachment
request = new RestRequest(string.Format("issue/{0}/attachments", res.Data.key), Method.POST);
request.AddHeader("X-Atlassian-Token", "nocheck");
var file = File.ReadAllBytes(#"C:\FB_IMG_1445253679378.jpg");
request.AddHeader("Content-Type", "multipart/form-data");
request.AddFileBytes("file", file, "FB_IMG_1445253679378.jpg", "application/octet-stream");
var res2 = client.Execute(request);
Console.WriteLine(res2.StatusCode == HttpStatusCode.OK ? "Attachment added!" : res2.Content);
#endregion
}
else
Console.WriteLine(res.Content);
}
}
public class Issue
{
public string id { get; set; }
public string key { get; set; }
public Fields fields { get; set; }
}
public class Fields
{
public Project project { get; set; }
public IssueType issuetype { get; set; }
public string summary { get; set; }
public string description { get; set; }
}
public class Project
{
public string id { get; set; }
public string key { get; set; }
}
public class IssueType
{
public string id { get; set; }
public string name { get; set; }
}
}
The whole code is on gist https://gist.github.com/gandarez/c2c5b2b27dbaf62a0d634253529bcb59
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?