Converting PHP array to C# when calling API - c#

I've looked at several related examples on SO and tried a number of methods to get this to work, but I become more confused with each attempt.
I'm trying to search through the Wordpress.org plugin repository API and get a list of plugins from the search results.
The endpoint is: http://api.wordpress.org/plugins/info/1.0/
The two important bits of data to pass are "action" and "search." The action I'm interested in at the moment is "query_plugins", and passing a search string along in the request.
This is a PHP equivalent:
$payload = array(
'action' => 'query_plugins',
'request' => serialize(
(object)array(
'search ' => 'search-phrase',
)
)
);
$body = wp_remote_post( 'http://api.wordpress.org/plugins/info/1.0/', array( 'body' => $payload) );
The only real documentation I've been able to find is from this blog post (which is where I got the above sample code): https://dd32.id.au/projects/wordpressorg-plugin-information-api-docs/
I'm using RestSharp to build the request, with code along these lines:
var client = new RestClient("http://api.wordpress.org/");
var request = new RestRequest("plugins/info/1.0", Method.POST);
request.AddParameter("XXX", "XXX");
var response = client.Execute(request);
var content = response.Content;
the "request.AddParameter("XXX", "XXX"); above is where I'm stuck. I need to build the PHP array equivalent in C# (and serialize it properly?) so that the API will accept the request. I've tried several variants and combinations, from everything as primitive as:
request.AddParameter("action", "query_plugins");
request.AddParameter("search", "keyword");
// and variants such as request.AddParameter("request", "[{ search: keyword }]);
Which I knew wouldn't work (but took a stab with anyway), to using a Dictionary() with the action and search parameters, and attempting to serialize it in several ways (most recent involved JsonConvert.SerializeObject).
At this point I don't know which tree I should be barking up, I have a feeling I'm not even in the right vicinity. I'm not even sure if I should be serializing to JSON, XML, or just a byte-stream (as I understand that's what the PHP serialize() method does, if I'm not mistaken), and I'm not sure the best approach to package all of the data I need to send off in the request.

This seems to work. Instead of POST, use GET
See the working sample here..
https://dotnetfiddle.net/rvL9eC
var client = new RestClient("http://api.wordpress.org/");
var request = new RestRequest("plugins/info/1.0", Method.GET);
request.AddParameter("action", "query_plugins");
request.AddParameter("search", "oauth");
var response = client.Execute(request);
var content = response.Content;

Related

What's is the equivalent to this code in C#

Situation
I'm tyring to send a certain message to every friend of my LINE's developer account.
I have no idea how to do that, but I already created it in PHP.
But again I don't know how to do this in C#.
Here is some information about my editor and stuff.
Editor: Visual Studio 2017
Template: I got "LINE Bot C# Template" in https://marketplace.visualstudio.com/items?itemName=pierre3.LINEBotCSharpTemplate
Project: I created the project with "LINEBotApplication"
What I want to do
I want to convert the code below to C#.
<?php
// HTTP REQUEST
$ch = curl_init('https://api.line.me/v2/bot/message/push');
$options = [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_BINARYTRANSFER => true,
CURLOPT_HEADER => true,
CURLOPT_POSTFIELDS => $post,
];
curl_setopt_array($ch, $options);
// To execute
$result = curl_exec($ch);
// To check eroors
$errno = curl_errno($ch);
if ($errno) {
return;
}
// To get HTTP status
$info = curl_getinfo($ch);
$httpStatus = $info['http_code'];
$responseHeaderSize = $info['header_size'];
$body = substr($result, $responseHeaderSize);
// If 200
echo $httpStatus . ' ' . $body;
What I'm not sure
I don't know how to fully convert the given code.
I may be able to convert "curl_init" method, by looking at
How to send data using the webrequest class
But with the remaining code I need assistance to convert it.
If you need more, I'd love to share.
中井さん、StackOverflowへようこそ!
I don't know much about PHP, but it seems to me your code is not doing anything other than sending a simple HTTP POST request. You can achieve the same thing in C# using a WebRequest. This should help:
https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest?view=netframework-4.8
EDIT:
Regarding what you asked in your comment, you can't just add the options to the WebRequest as an array like in PHP. Those API's are just different. For example you'd make a WebRequest like this
WebRequest myWebRequest=WebRequest.Create("https://api.line.me/v2/bot/message/push");
then instead of
CURLOPT_HTTPHEADER => $headers,
You would do
myWebRequest.Headers.Add([header name], [header value]);
for every header you need to add. (Or maybe there's a way of adding a collection of headers)
And so on.
Also, in researching how to do a POST with a WebRequest, it seems quite clumsy. So you might want to use HttpClient instead. Here's more on which one to choose.
https://www.infoworld.com/article/3198673/my-two-cents-on-webclient-vs-httpclient-vs-httpwebrequest.html
Bottom line is, it's not that straightforward to just rewrite something from PHP to C#. Those are two very different beasts. So you need to do a bit more studying.
Or maybe someone will come along and give you the answer :)
Welcome to SO and C#. I haven't worked with LINE Bot but I thought I'd provide a generic example which might help understanding working with HTTP request in C#.
I have created this sample app for you as an example, using .NET Core and HttpClient. Just create a simple console app and paste the following code into Program.cs file:
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static async Task Main()
{
var client = new HttpClient();
var content = new StringContent("{ \"your\": \"content\", \"maybe\": \"json\" }");
content.Headers.Add("X-SOME-RANDOM", "header-value");
var response = await client.PostAsync("https://httpbin.org/post", content);
var httpStatus = response.StatusCode;
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine($"{httpStatus} {body}");
}
}
}
I hope it helps a bit. Have fun!
PS Thanks to httpbin.org for the handy service.

RestSharp PUT request parameters

I'm having issues figuring out how to create a put request using RestSharp.
I need to pass an integer followed by a JSON body in the same request.
So far I have this:
for (var i = 0; i < ReorderedTasks.Count; i++) {
var reorderedTasksJson = new JavaScriptSerializer().Serialize(ReorderedTasks[i]);
var request = new RestRequest("api/task/5/{ID}/", Method.PUT);
request.AddParameter("ID", ReorderedTasks[i].ID.ToString(), ParameterType.UrlSegment);
request.AddParameter("application/json; charset=utf-8", reorderedTasksJson, ParameterType.RequestBody);
client.Execute(request);
}
I've tested out the JSON ad requestBody on POST and it works fine. I think my issue is with the first parameter I'm trying to pass ReorderedTasks[i].ID , I'm not sure if I'm handling the passing of this correctly.
I've initialised client at the beginning of my class.
Problem is the DB isn't updating and I need to isolate the problem. Is the above the correct way in dealing with my two parameters needing passed?
I suggest to put ReorderedTasks[i].ID.ToString() directly to url path.
var request = new RestRequest($"api/task/5/{ReorderedTasks[i].ID.ToString()}/", Method.PUT);
It will help to reduce possible problems with http request format.
I'll add it here, so someone will benefit from it.
If your endpoint URL have parameters like ?param=value&param2=value that you want to pass along with request RestSharp's AddParameter(string, string) won't work with PUT method (but it works just fine with GET or if endpoint doesn't have URL parameters, so it is deceiving)
Use AddParameter(string, string, ParameterType.QueryString) in order to PUT Method work correctly.
Well it depends on what does the webApi expect..
You could use Fiddler to inspect what being sent through the wire and what response You are getting (http://www.telerik.com/fiddler)
Also - here are some sample's how other users use RestSharp
How do I use PUT in RestSharp?

previewing what a .NET HttpResponse object will post (obtaining cURL or similar serialised output)

I am not getting the response I am wanting for the following code:
var multipart = new MultipartFormDataContent();
var empty = Encoding.ASCII.GetBytes("\r\n\r\n\r\n");
HttpContent content = new ByteArrayContent(empty);
content.Headers.Add("name", "jform[ical_url]");
multipart.Add(content);
...[cut for brevity]...
using (var handler = new HttpClientHandler { UseCookies = false })
using (var client = new HttpClient(handler) { BaseAddress = new System.Uri("http://icalendar.org") })
{
var response = await client.PostAsync("/validator", multipart);
I know exactly what I would like the POST request to look like (having used Firebug's 'copy cURL' menu item).
Is there a way to see what the client.PostAsync will send, or an extension to serialise the multipart variable above so that I can compare with the cURL string from a successful post?
Thank you.
Overriding the delegating handler has provided some of the answer, as per this SO answer.
I had not clearly explained that this was a class library. I tried Crowcoders advice, but I couldn't get it to work, and as the entire solution contains no WebAPI or MVC or similar projects, and I am trying to post to a validation site to check certain unit tests meet a spec. Briefly looking through the Stackify Prefix docs, I think the ability to handle this kind of scenario is in the pipeline, but not released as yet.
As I would love to know if any defaults are being added to the header (Accept, Language etc), I might look at Fiddler.

How can I "pass through" the raw json response from a NEST Elasticsearch query?

Our client side code works directly with elasticsearch responses, but I want to put NEST in the middle to do some security and filtering. What is the easiest way to build a query with NEST (or elasticsearch.net) and then just pass the raw json response back out to my client with the least amount of processing. I'm using ServiceStack as well by the way.
Previous similiar question has now an outdated answer - Returning Raw Json in ElasticSearch NEST query
Thanks
This is for the benefit of readers who want to achieve the same thing in newer versions of NEST, v2.3 as of this writing. If you just want the response, all you need to do is this using the ElasticLowLevelClient, according to the doc:
var responseJson = client.Search<string>(...);
But if you want the typed results as well then it's slightly more involved. You need to call DisableDirectStreaming() on the settings object and then retrieve the raw json from response.ApiCall.ResponseBodyInBytes as demonstrated here.
var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
.DefaultIndex("index1")
.DisableDirectStreaming();
var response = new ElasticClient(settings)
.Search<object>(s => s.AllIndices().AllTypes().MatchAll());
if (response.ApiCall.ResponseBodyInBytes != null)
{
var responseJson = System.Text.Encoding.UTF8.GetString(response.ApiCall.ResponseBodyInBytes);
}
Elasticsearch.Net allows you to return the response stream directly,
var search = client.Search<Stream>(new { size = 10 });
.Search() has many overloads to limit its scope by index and type.
This will return an IElasticsearchResponse<Stream> where you can pass the response stream directly to the deserializer of your choide (SS.Text in your case) without the client buffering in between.

Desk.com and RestSharp (oAuth)

This feels like it should be easy but...it's not. It definitely doesn't help that there's no library for Desk.com, and the documentation is (in my opinion) extremely thin and lacking.
Anyway, I'm trying to use RestSharp to do something simple: grab recent cases. I'm using the Single Access Token method as we don't need to interact as any of our users.
Here's the code:
var client = new RestClient();
client.Authenticator = RestSharp.Authenticators.OAuth1Authenticator.ForProtectedResource("key","secret","token","token secret");
client.BaseUrl = "http://xxx.desk.com/api/v1/";
var request = new RestRequest();
request.Method = Method.GET;
request.Resource = "cases.json?count=10&status=new";
request.RequestFormat = DataFormat.Json;
var result = client.Execute(request);
Result always just says the auth request was invalid and is unauthorized. Tried a bunch of different combinations, looked through the tests that are part of the RestSharp library, and read every meager word of the Desk.com documentation. Just not sure what to try next.
You may have figured this out already, but you get that unauthorized message when you try to add the querystring to the RestRequest's Resource.
I was having the same problem. Daniel's "account/verify_credentials.json" worked for me too, so that's when I started to wonder if it had something to do with the querystring.
var request = new RestRequest();
request.Method = Method.GET;
request.Resource = "cases.json";
request.RequestFormat = DataFormat.Json;
request.AddParameter("count", 10);
request.AddParameter("status", "new");
I just wanted to say, that after following a lot of examples on making the Desk API work with C#, yours was actually the only one that did work.
I did not test with the resource you specified above, but used your code together with the "account/verify_credentials.json" resource. It returns an OK response for me, so your code works. So, first of all...thank you :)
Second (sorry if I am stating the obvious), I assume that you do not use the ("key", "secret", "token", "token secret") parameters as you specified them here, but use valid ones. You most probably do, but mayyybe there is a small chance that you may have found and copied that piece of code from somewhere else, and perhaps missed filling in your info.
EDIT: Since my first answer, I have put together a small (really small) SDK that can be used to connect to and work with the API in C#. You can grab the source code here: http://danielsaidi.github.com/desk-csharp-sdk/
Hope you get it to work.

Categories

Resources