What's is the equivalent to this code in C# - 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.

Related

Getting "Bad Request" when using RestSharp

I am living in Denmark where we have the ability to pull all data regarding our power usage from the website Eloverblik.dk.
They have even provided a nice API, so you can make your own programs that pulls the data from their website:
https://api.eloverblik.dk/CustomerApi/index.html
However:
Assume you have the following C# prof of concept code:
using RestSharp;
using RestSharp.Authenticators;
var token = "eyJ...";
var client = new RestClient("https://api.eloverblik.dk")
{
Authenticator = new JwtAuthenticator(token)
};
/* Get power usage from June 1st 2022 until September 1st 2022 */
var request = new RestRequest("api/meterdata/getmeterreadings/2022-06-01/2022-09-01");
var response = await client.GetAsync(request);
Console.WriteLine(response.Content);
When I run the code I get an error code "BadRequest" when I try to call await client.GetAsync.
What am I doing wrong?
They write in the API that the token is formattet as Bearer {token}, but I thought that JwtAuthenticator did that for me?
It seems that you call API incorrectly.
Check again documentation on API at https://api.eloverblik.dk/CustomerApi/index.html.
getMeterReadings is a POST method, not a GET (so, you need to call client.PostAsync and not client.GetAsync)
getMeterReadings expects also JSON-body to be sent (with list of metering points).
Also, I would recommend you to test your requests using some HTTP-request tool (i.e. Postman) and when you're pretty sure that request works move it into C#.

API GET Request Returns HTML/Text instead of JSON

This is my first time working with a RESTful API and Xamarin and etc. I have so far made a simple REST API. I have written a GET call to it that, if I write http://localhost:[num]/api/Name, it will return a JSON file of the matching Emu's information. I have tested this with Postman, so I know that it works.
I have now written an app that will call this API in order to catch this information and then display it. So far, I've got it connected to the server hosting my API, but I'm unable to get it to return JSON. Instead it seems to be returning text/HTTP.
From what I've searched up on previous Stack Overflow threads, it seems that I was missing Headers requesting that reply be in a JSON format. When I added in code that was on the official .NET documentation on Microsoft's website, it gave me issues with my Json Deserialiser. I have also added in the information in the header to make sure that it returns json.
Here is the code for the function:
async private void Submit_OnClicked(object sender, EventArgs e)
{
var nameValue = EmuName.Text;
var baseAddr = new Uri("http://my_url/HelloEmu/");
var client = new HttpClient { BaseAddress = baseAddr };
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
string url = (string)nameValue;
var returnedJson = await client.GetStringAsync(url);
Models.EmuItemModel MyEmu = JsonConvert.DeserializeObject<Models.EmuItemModel>(returnedJson);
ReturnedName.Text = MyEmu.Name;
ReturnedAge.Text = MyEmu.Age.ToString();
ReturnedWeight.Text = MyEmu.Weight.ToString();
My code actually faults on the line ReturnedWeight.Text = MyEmu.Weight.ToString()
But I'm guessing the more majour issue is occuring during deserialisng the object, because it seemingly "skips" over the preceeding two lines when I run it in the debugger.
When I run it in Visual Studio 2019, the value of "returnedJson" is this:
"<html><head><meta http-equiv=\"refresh\" content=\"0;url=http://lookup.t-mobile.com/search/?q=http://my_url/HelloEmu/Keith&t=0\"/></head><body><script>window.location=\"http://lookup.t-mobile.com/search/?q=\"+escape(window.location)+\"&r=\"+escape(document.referrer)+\"&t=0\";</script></body></html>"
I think this is an HTML output. I would love any hints about what on earth I'm doing wrong!
EDIT: Since it almost seems like the HTML is returning an error message, perhaps it could do with my url??? I've published the website using the File system method. So to access the API in Postman I'll use http://localhost:[port]/api/values, calling my website in a regular ol' browser makes it go http://my_url/HelloEmu. I get a 403 "no directory" method in return...
EDIT: Here is the Postman code:
enter image description here
Usually it happens because there are missing headers or some other malformed request, Download RestSharp DLL from NuGet, and then you can use the following, in postman, go to "Code":
And choose C# you will see a code snippet (Example):

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.

Converting PHP array to C# when calling API

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;

Is there a .NET ready made method to process response body of a HttpListener HttpListenerRequest body?

I'm using HttpListener to provide a web server to an application written in another technology on localhost. The application is using a simple form submission (application/x-www-form-urlencoded) to make its requests to my software. I want to know if there is already a parser written to convert the body of the html request document into a hash table or equivalent.
I find it hard to believe I need to write this myself, given how much .NET already seems to provide.
Thanks in advance,
You mean something like HttpUtility.ParseQueryString that gives you a NameValueCollection? Here's some sample code. You need more error checking and maybe use the request content type to figure out the encoding:
string input = null;
using (StreamReader reader = new StreamReader (listenerRequest.InputStream)) {
input = reader.ReadToEnd ();
}
NameValueCollection coll = HttpUtility.ParseQueryString (input);
If you're using HTTP GET instead of POST:
string input = listenerRequest.Url.QueryString;
NameValueCollection coll = HttpUtility.ParseQueryString (input);
The magic bits that fill out HttpRequest.Form are in System.Web.HttpRequest, but they're not public (Reflector the method "FillInFormCollection" on that class to see). You have to integrate your pipeline with HttpRuntime (basically write a simple ASP.NET host) to take full advantage.
If you want to avoid the dependency on System.Web that is required to use HttpUtility.ParseQueryString, you could use the Uri extension method ParseQueryString found in System.Net.Http.
Make sure to add a reference (if you haven't already) to System.Net.Http in your project.
Note that you have to convert the response body to a valid Uri so that ParseQueryString (in System.Net.Http)works.
string body = "value1=randomvalue1&value2=randomValue2";
// "http://localhost/query?" is added to the string "body" in order to create a valid Uri.
string urlBody = "http://localhost/query?" + body;
NameValueCollection coll = new Uri(urlBody).ParseQueryString();

Categories

Resources