convert curl php rest api calls to c# code - c#

I've been trying to convert php code that accesses a json rest api into c# but cannot get this to work...
I cannot get a valid response back.. (400 Bad request)
Here is the curl im trying to convert:
curl --user bob#gmail.com:387653t253431a1b1d6687pl9836th5s \
--form url=http://bbc.com --form x-metrix-adblock=0 \
https://gtmetrix.com/api/0.1/test
Here is the code I've tried without success:
content = "http://bbc.com";
string result;
var req = HttpWebRequest.Create("https://gtmetrix.com/api/0.1/test");
req.Method = "POST";
var cc = new CredentialCache();
req.Credentials = new NetworkCredential(username, passkey);
req.ContentType = "application/json";
byte[] bytes = UTF8Encoding.UTF8.GetBytes(content);
req.ContentLength = bytes.Length;
using (var stream = req.GetRequestStream())
{
stream.Write(bytes, 0, bytes.Length);
}
using (var resp = req.GetResponse())
{
var results = new StreamReader(resp.GetResponseStream()).ReadToEnd();
result = JObject.Parse(results).ToString();
}
any help would be appreciated..

This is not a direct answer to your question, but I wanted to let you know that I’ve released an open source .Net client library which simplifies consuming the GTMetrix.net API. Submitting a test and retrieving the results is simple;
var client = Client(connection);
var request = new TestRequest(
new Uri("http://website.net"),
Locations.London,
Browsers.Chrome);
var response = client.SubmitTestAsync(request);
if (response.Result.StatusCode == HttpStatusCode.OK &&
response.Result.Body.State == ResultStates.Completed)
{
var pageLoadTime = response.Result.Body.Results.PageLoadTime;
...
}
The project (docs and code) can be found here GTmetrix-net on GitHub

Related

C# how to consume rest web service

I am having a problem when I try using a rest web service in C#.
When I try via Fiddler it works Ok.
When I try via HTML/Ajax, it works Ok, as well.
When I try via C# (Console Application) I get an error.
This image is captured in fiddler. It is what I get when I try via ajax
this image is also captured in fiddler. It is what I get when I try via C#
As you can see, the JSON field is empty.
This is my C# code
string json = JsonConvert.SerializeObject(abc);
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("MyURL"); //==> I am filling it correctly
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.PostAsJsonAsync("MyMethod", json).Result; //==> I am filling my method correctly
But I have tried several others and always getting the same problem. (the code bellow is another one I tried)
var requisicaoWeb = WebRequest.CreateHttp("MyURL");
requisicaoWeb.Method = "POST";
requisicaoWeb.ContentType = "application/json";
requisicaoWeb.ContentLength = dados.Length;
requisicaoWeb.UserAgent = "Console app";
requisicaoWeb.Accept = "Accept:application/json,text/javascript,*/*;q=0.01";
//precisamos escrever os dados post para o stream
using (var stream = requisicaoWeb.GetRequestStream())
{
stream.Write(MyJson, 0, dados.Length);
stream.Close();
}
//ler e exibir a resposta
using (var resposta = requisicaoWeb.GetResponse())
{
var streamDados = resposta.GetResponseStream();
StreamReader reader = new StreamReader(streamDados);
object objResponse = reader.ReadToEnd();
var post = objResponse.ToString();//JsonConvert.DeserializeObject<Post>(objResponse.ToString());
streamDados.Close();
resposta.Close();
}
Everything I try in C#, the JSON field on Fiddler is always empty and the "syntax View" description is always "Request Invalid".
Try it's;
public static string HttpPost(string URI, string Parameters)
{
System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
req.ContentType = "application/json; charset=utf-8";
req.Method = "POST";
req.Timeout = 600000;
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
System.Net.WebResponse resp = req.GetResponse();
if (resp == null)
return null;
System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
return sr.ReadToEnd().Trim();
}
I have just figure it out.
If anybody else has the same problem, here is the answer
string json = JsonConvert.SerializeObject(abc);
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("MyURL"); //==> I am filling it correctly
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var stringContent = new StringContent(JsonConvert.SerializeObject(abc), Encoding.UTF8, "application/json");
var response = client.PostAsync("MyURL", stringContent).Result; //==> I am filling my method correctly

PHP/Curl-SSL operations alternative in C#

I have this piece of code written in PHP, which adds, as i presume, some information about an SSL-certificate to a HTTP-request(It's just a simple http-request, isn't it?). It's added either to body-request or header, that i don't know for sure.
//some code before that
curl_setopt($curl,CURLOPT_SSLCERT,'cert.crt');
curl_setopt($curl,CURLOPT_SSLKEY,'cert.key');
//some code after
//the request itself
$json_response = curl_exec($curl);
The problem is - i don't know how to make this stuff in C#. It'd be easy if i had any knowledge how it's done in curl, like what it exactly does under it's cover.
My current request.
//
var request = CreateHttpRequest(url, method);
var json = param?.ToJson();
if (json != null)
{
var postData = Encoding.UTF8.GetBytes(json);
request.ContentLength = postData.Length;
using (var stream = request.GetRequestStream())
stream.Write(postData, 0, postData.Length);
}
using (var webResponse = request.GetResponse())
using (var streamReader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
{
var result = streamReader.ReadToEnd();
return result.ParseJson(type);
}
//
private HttpWebRequest CreateHttpRequest(string url, HttpMethod method)
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/json";
request.Accept = "application/json, application/javascript, text/*";
request.Headers.Add("Accept-Encoding", "gzip,deflate");
request.Method = method.ToString().ToUpper();
return request;
}
In order to use client certificate (loaded from .crt and .key files) in your HTTP-request, add following lines in CreateHttpRequest method before return:
string certificateText = File.ReadAllText("cert.crt");
string privateKeyText = File.ReadAllText("cert.key");
ICertificateProvider provider =
new CertificateFromFileProvider(certificateText, privateKeyText);
request.ClientCertificates.Add(provider.Certificate);
Taken from this answer. To have CertificateFromFileProvider install OpenSSL.X509Certificate2.Provider Nuget package.
Ended up using OpenSSL library.
public X509Certificate2 CreateCertifacte(string pathToCertificate)
{
var keyBytes = File.ReadAllBytes($"{pathToCertificate}/cert.key");
var certBytes = File.ReadAllBytes($"{pathToCertificate}/cert.crt");
var certBio = new BIO(certBytes);
var keyBio = new BIO(keyBytes);
var key = CryptoKey.FromPrivateKey(keyBio, "_");
var cert = new X509Certificate(certBio);
var name = cert.SerialNumber+".pfx";
var stacks = new Stack<X509Certificate>();
new X509Store().AddTrusted(cert);
var certRealPkcs12 = new PKCS12("_", key, cert, stacks);
using (var file = BIO.File(name, "wb"))
{
file.SetClose(BIO.CloseOption.Close); // don't ask me why, i don't know. this one just works.
certRealPkcs12.Write(file);
}
certRealPkcs12.Dispose();
var realCertOut =
new X509Certificate2(File.ReadAllBytes(name), "_");
return realCertOut;
}
Update:
For the netstandard version you can use my fork. Keep in mind that it hasn't been tested all the way through yet (not sure if i ever will), so something wont probably work.

I am trying to convert curl request to c# request but it is not working

I am trying to convert a curl request to c# request but it is not working
curl request
curl -X GET "http://www1.bloomingdales.com/shop/search?keyword=lace%2Btop"
The above curl request works fine
C# request
public lib_check ()
{
string url_1 = "http://www1.bloomingdales.com/shop/search/Pageindex%2CProductsperpage/1%2C180?keyword=women%20tank%20top";
Console.Write (url+"request started");
var request = (HttpWebRequest)WebRequest.Create(url_1);
request.Method = WebRequestMethods.Http.Get;
var response = request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
var json = reader.ReadToEnd ();
console.write( json);
}
}
But the above c# request throws 403 forbidden error
How to fix c# request and make request working to get 200 response?
I guess the reason why it's forbidden because you didn't construct the necessary header that the site is expecting. You need to construct those headers and you can check it in developer tools in chrome. See code below.
string url_1 = #"http://www1.bloomingdales.com/shop/search/Pageindex%2CProductsperpage/1%2C180?keyword=women%20tank%20top";
var request = (HttpWebRequest)WebRequest.Create(url_1);
request.Method = "GET";
request.Accept = "text/html";
request.UserAgent = ".NET Framework Test Client"; // Some server prevent script like this so they validate some user-agents
request.MaximumAutomaticRedirections = int.MaxValue;
request.Timeout = 50000;
var response = request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
var json = reader.ReadToEnd();
Console.Write(json);
}
To see what are the headers needed by the server; try requesting the url in browser first while dev tools are active.
Update : If this doesn't work well due to timeout issue it better to handle it asynchronously.
var handler = new HttpClientHandler
{
AllowAutoRedirect = true,
CookieContainer = new CookieContainer(),
UseCookies = true,
AutomaticDecompression = DecompressionMethods.Deflate
};
var client = new HttpClient(handler)
{
Timeout = new TimeSpan(0, 3, 0)
};
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
client.DefaultRequestHeaders.ExpectContinue = false;
client.DefaultRequestHeaders.Add("Accept-Language", "en-US, en");
var result = client.GetAsync("http://www1.bloomingdales.com/shop/search/Pageindex%2CProductsperpage/1%2C180?keyword=women%20tank%20top").Result;
var content = result.Content.ReadAsStringAsync().Result;
Console.Write(content);
I noticed the result is not json but a page. May be because it's not API. Adjust the code as needed but the bare bone was already there.

Posting to Facebook - Graph API

I have managed to successfully read my Facebook account by using the following code:
IAuthorizationState authorization = client.ProcessUserAuthorization();
if (authorization == null)
{
// Kick off authorization request
client.RequestUserAuthorization();
}
else
{
var request = WebRequest.Create("https://graph.facebook.com/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
Session["access_token"] = authorization.AccessToken;
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
var graph = FacebookGraph.Deserialize(responseStream);
this.nameLabel.Text = HttpUtility.HtmlEncode(graph.Name);
}
}
}
I am now trying to POST to my Facebook news feed and I am struggling to find a guide to help me through it. I have tried to start it myself and for some reason it seems to throw back a 400: Bad Request error.
var request = WebRequest.Create("https://graph.facebook.com/me/feed?");
var postdata = "message=hello";
postdata += "&access_token" + Session["access_token"].ToString();
var data = Encoding.ASCII.GetBytes(postdata);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Can anyone help me understand why my code is returning the error?
Use http://facebooksdk.net/ to make your job simple. Store access token and reuse for every request till it gets expired.

Creating CURL Request ASP.NET

curl -X POST 'https://api.twilio.com/2010-04-01/Accounts/AC053acaaf55d75ef32233132196e/Messages.json' \
--data-urlencode 'To=5555555555' \
--data-urlencode 'From=+15555555555' \
--data-urlencode 'Body=Test' \
-u AC053acaaf55d75a393498192382196e:[AuthToken]
I have the above curl code for an API I need to connect to. The problem is I need to connect using ASP.NET (C#). I'm not very familiar with ASP.NET and don't really know where to begin. I know how to code this in PHP but ASP.NET is another matter. From the research I've done I need to use WebRequest. How do I feed in the post data and the authtoken (-u AC053acaaf55d75a393498192382196e:[AuthToken]) part of the request.
string url = "https://api.twilio.com/2010-04-01/Accounts/AC053acaaf55d75ef32233132196e/Messages.json";
WebRequest myReq = WebRequest.Create(url);
myReq.Method = "POST";
Twilio evangelist here.
Just to make sure we are on the same page, you need to make a POST request to theMessages endpoint in the Twilio API, but you cannot use our helper library.
Not a problem, you can just use .NETs native HTTP client libraries, HttpWebRequest and HttpWebResponse. Thats going to look something like this:
//Twilio Credentials
string accountsid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string authtoken = "asdsadasdasdasdasdsadsaads";
//Twilio API url, putting your AccountSid in the URL
string urltemplate = "https://api.twilio.com/2010-04-01/Accounts/{0}/Messages.json";
string url = string.Format(urltemplate, accountsid);
//Create a basic authorization
string basicauthtoken = string.Format("Basic {0}", System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(accountsid + ":" + authtoken)));
//Build and format the HTTP POST data
string formencodeddata = "To=+15555555555&From=+15556666666&Body=Hello World";
byte[] formbytes = System.Text.ASCIIEncoding.Default.GetBytes(formencodeddata);
//Create a new HTTP request object, set the method to POST and write the POST data to it
var webrequest = (HttpWebRequest)WebRequest.CreateHttp(url);
webrequest.Method = "POST";
webrequest.ContentType = "application/x-www-form-urlencoded";
webrequest.Headers.Add("Authorization", basicauthtoken);
using (Stream postStream = webrequest.GetRequestStream()) {
postStream.Write(formbytes, 0, formbytes.Length);
}
//Make the request, get a response and pull the data out of the response stream
var webresponse = (HttpWebResponse)webrequest.GetResponse();
Stream responseStream = webresponse.GetResponseStream();
var reader = new StreamReader(responseStream);
string result = reader.ReadToEnd();
There are also async versions of the GetRequestStream and GetResponse methods if you need them.
Hope that helps.
Twilio has some great docs for this here: http://www.twilio.com/docs/api/rest/making-calls
they also have a great c# library here; twilio.com/docs/csharp/install but here's an example in C# showing how to make a call.
using System;
using Twilio;
class Example {
static void Main(string[] args) {
// Find your Account Sid and Auth Token at twilio.com/user/account
string AccountSid = "AC3094732a3c49700934481addd5ce1659";
string AuthToken = "{{ auth_token }}";
var twilio = new TwilioRestClient(AccountSid, AuthToken);
var options = new CallOptions();
options.Url = "http://demo.twilio.com/docs/voice.xml";
options.To = "+14155551212";
options.From = "+14158675309";
var call = twilio.InitiateOutboundCall(options);
Console.WriteLine(call.Sid);
}
}
Working code for me
string accountsid = "AccountSid";
string authtoken = "AuthToken";
//Twilio API url, putting your AccountSid in the URL
string urltemplate = "https://api.twilio.com/2010-04-01/Accounts/{0}/Messages.json";
string url = string.Format(urltemplate, accountsid);
//Get Client Secret and client key from the API Keys section-- https://www.twilio.com/docs/iam/keys/api
string basicauthtoken = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("ClientSecret:ClientKey"));
//Build and format the HTTP POST data
string formencodeddata = "To={To}&From={From}&Body={Body}";
byte[] formbytes = System.Text.ASCIIEncoding.Default.GetBytes(formencodeddata);
//Create a new HTTP request object, set the method to POST and write the POST data to it
var webrequest = (HttpWebRequest)WebRequest.CreateHttp(url);
webrequest.Method = "POST";
webrequest.ContentType = "application/x-www-form-urlencoded";
webrequest.Headers.Add("Authorization", basicauthtoken);
using (Stream postStream = webrequest.GetRequestStream())
{
postStream.Write(formbytes, 0, formbytes.Length);
}
//Make the request, get a response and pull the data out of the response stream
var webresponse = (HttpWebResponse)webrequest.GetResponse();
Stream responseStream = webresponse.GetResponseStream();
var reader = new StreamReader(responseStream);
string result = reader.ReadToEnd();

Categories