Visual C# make web request like python's - c#

i'm having a little piece of python code which makes a web request using the urllib2 as you can se below
import json
import urllib2
urlRequest = urllib2.Request('<link>')
urlRequest.add_header('Content-Type', 'application/json')
urlRequest.add_header('RegistrationToken', '<token>')
data = {
'content': '<c>',
'messagetype': 'RichText',
'contenttype': 'text',
'id': '<id>'
}
urllib2.urlopen(urlRequest, json.dumps(data))
As i was trying to do it in C# i came across the following problems
how to i send the data
how do i add the headers?
After googling for a while i managed to write this code:
var request = (HttpWebRequest)WebRequest.Create(url_input.Text);
request.ContentType = "application/json";
request.Headers["RegistrationToken"] = rtoken_input.Text;
request.GetResponse();
I managed to deal with the headers part but the question on the data still remains. Also what is the best way to json encode something?
Anyone who knows what to do?

If you are after serializing the POST data to a JSON payload there are few options.
1) System.Web.Helpers.Json.Encode MSDN Link
2) using the JSON.NET library Link
As for your attempt on converting python to C# you are on the correct track.
Refer to this link
Alternatively you could make use of the WebClient class MSDN Link
Refer to this link as well
Pseudo code
var client = new WebClient();
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("RegistrationToken", "<token>");
string response = client.UploadString("<link>", "<json string>");

Related

upload feed to walmart

I am breaking my head trying to upload a feed to walmart, after many times trying i used postman to generate C# restsharp code for me, in postman it works, but when using the c# restsharp code it returns a mysterious error. like this:
"No message body writer has been found for response class FeedAcknowledgement"
what does that mean?
here is my code:
string requestUrl = "";
requestUrl = string.Format("https://marketplace.walmartapis.com/v2/feeds?feedType=inventory");
string method = "POST";
// string[] sig = getSig(method, requestUrl).Replace("\r", "").Split('\n');
var mySig = new Signature(ConsumerID, SecretKEY, requestUrl, method);
var s = mySig.TimeStamp;
var returendSigniture = mySig.GetSignature(s);
var client = new RestClient("https://marketplace.walmartapis.com/v2/feeds?feedType=inventory");
var request = new RestRequest(Method.POST);
//request.AddHeader("postman-token", "c325ba5f-813a-f990-7899-6bfc4b14aa1b");
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
request.AddHeader("accept", "application/xml");
request.AddHeader("wm_consumer.id", "--");
request.AddHeader("wm_sec.auth_signature", returendSigniture);
request.AddHeader("wm_sec.timestamp", mySig.TimeStamp);
request.AddHeader("wm_qos.correlation_id", "123456abcdef");
request.AddHeader("wm_svc.name", "Walmart Marketplace");
request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"BOUNDERY\"\r\n\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<wm:inventory xmlns:wm=\"http://walmart.com/\">\n <wm:sku>PP00500-2PC</wm:sku>\n <wm:quantity>\n <wm:unit>EACH</wm:unit>\n <wm:amount>120</wm:amount>\n </wm:quantity>\n <wm:fulfillmentLagTime>1</wm:fulfillmentLagTime>\n</wm:inventory>\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
I spent all day in figuring out how to request Walmart v3. I propose you the following two steps:
Use Walmart signer in order to generate signed token.
You will need to use HttpWebRequest for getting response from Walmart in a way similar to what is described here.
I have not been able to get this to work natively in C#, but I do have a work around.
The Java SDK can successfully submit multi-part requests to Walmart. I wrote a wrapper around the SDK functions that can accept basic command line input to read a text file and send the appropriate call with attached files. From here, you can just call the .jar file (I do it via dynamically generated batch file) from your C# program and receive responses back via text file. This is a sub-optimal system, but it works reliably and when the choice was between updating inventory on 2000 items every day and using some dirty code, I went with the Java wrapper method. This will be replaced as soon as the C# SDK comes out, but I believe this is one of the reasons why the C# SDK may be being delayed.
This solution was used, only after spending about a week trying to get boundaries / streams / attachments to work in C# and having zero success. Cases were also submitted to walmart and I was able to work with some of their top tier engineering support staff and this problem completely stumped them. I was able to trace the Java SDK execution all the way down to a built in Maven / Java function that constructed the web request so there's something under the hood that Java is doing with a multi-part request that isn't immediately clear in C#.

Firebase in c# (API recommendation)

I am trying to make a simple program using a firebase database. But i would like to code my client in C# is there any good APIs available? I found a few but some are lacking functions and i would like to know the opinion of someone more experienced in these waters.
There is a REST API which is fairly portable, and you can use this from any .NET language on any supported platform. Dina Cruz has a thorough example of using this API, and you could easily convert this info and use the portable/basic HttpWebRequest type from the BCL instead of whatever Dina used, for example, this is a transliteration of the first POST example from Dina's blog:
var json = Newtonsoft.Json.JsonConvert.SerializeObject(new
{
user = "UserNameValue",
message = "MessageValue"
});
var request = WebRequest.CreateHttp("https://tm-admin-test.firebaseio.com/.json");
request.Method = "POST";
request.ContentType = "application/json";
var buffer = Encoding.UTF8.GetBytes(json);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
var response = request.GetResponse();
json = (new StreamReader(response.GetResponseStream())).ReadToEnd();
// TODO: parse response (contained in `json` variable) as appropriate
There are also several open source projects including Fire#, FirebaseDatabase.net and FirebaseSharp. I'm not sure if these support "all the things."
References
Firebase REST API on google.com
C# example of using Firebase REST API on dinacruz.com
REST examples in C# using WebRequest on StackOverflow.com
Fire# project on github.com
FirebaseDatabase.net project on github.com
FirebaseSharp project on github.com

Get JSON string from HTTP GET request

Using fiddler to observe this URL:
http://opencaselist.paperlessdebate.com/bin/AllDocs?view=attachments#format=json?|t=allattachments&p=1&l=10&s=filename&d=asc
I find a nice JSON response like this
How do I get this response into a string that I can save in a txt file using C#? Is there a way to turn an HTTP Web Response to a string? Is there something is NewtonSoft JSON that can help me? Are there particular terms that will help me google this more effectively?
Every time I try I just get an HTML version of the web-page at the link and not the JSON data I'm trying to get:
string url = "http://opencaselist.paperlessdebate.com/bin/AllDocs?view=attachments#|t=allattachments&p=1&l=10&s=filename&d=asc";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Method = WebRequestMethods.Http.Get;
httpWebRequest.Accept = "text/json";
httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
response.Close();
Note that on that screenshot, there are some differences:
the URL is way different: AllAttachements vs AllDocs, but that's minor, I'm pointing it out "just in case"
the PARAMS are way different: the screenshot specifies xpage=plain&outputSyntax=plain and your code - not
the HEADERS are different: your code has Accept=text\json while screenshot has Accept: text/javascript
Have you tried using the same params and headers?
EDIT: also, I've opened up the page from your code, and it actually is a page. After loading, it generates additional requests to
http://opencaselist.paperlessdebate.com/bin/get/XWiki/AllAttachmentsResults?xpage=plain&outputSyntax=plain&offset=1&limit=10&reqNo=1&sort=filename&dir=asc
which, if you download, results in JSON data. No headers at all, simple GET. I've just got the JSON data by simply pasting that URL into Chrome.. I think that you simply use wrong URL.

How do I check for binary vs. text in an HttpWebRequest in c#?

Is there a way to determine if the response from an HttpWebRequest in C# contains binary data vs. text? Or is there another class or function I should be using to do this?
Here's some sample code. I'd like to know before reading the StreamReader if the content is not text.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.someurl.com");
request.Method = WebRequestMethods.Http.Get;
using (WebResponse response = request.GetResponse())
{
// check somewhere in here if the response is binary data and ignore it
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string responseDetails = reader.ReadToEnd().Trim();
}
}
In general, web sites will tell you in the Content-Type header what kind of data they're returning. You can determine that by getting the ContentType property from the response.
But sites have been known to lie. Or not say anything. I've seen both. If there is no Content-Type header or you don't want to trust it, then the only way you can tell what kind of data is there, is by reading it.
But then, if you don't trust the site, why are you reading data from it?

WebClient restful Delete

I have a simple Restful service being called from a console app so am using WebClient. I am wondering if this call for Delete is correct.
The url looks like localhost/RestService1/Person/1
using (var client = new WebClient())
{
client.UploadString(url, "DELETE", "");
}
I don't like that UploadString does not have an overload without a data parameter. The passing of an empty parameter is not sitting well with me. Is there a better method to use for a DELETE?
I could use WebRequest but I want to just use WebClient to keep it consistent.
Here is the WebRequest block
var request = WebRequest.Create(url);
request.Method = "DELETE";
var response = (HttpWebResponse)request.GetResponse();
Both blocks work fine but what is best? Or is there a better way?
The following works for me:
client.UploadValues(url, "DELETE", new NameValueCollection());
The WebClient class doesn't really lend well to restful api consumption, I've used 3rd party libraries like RestSharp in the past that are geared more towards this type of web request. I'm pretty sure RestSharp just uses HttpWebRequest under the covers, but it provides a lot of semantics that make consuming and reusing rest resources easier.
Go get the Microsoft.Net.Http client libraries http://nuget.org/packages/Microsoft.Net.Http
HttpClient is a much better client to use for working with an API.
Sorry this is my solution in vb.net i sure that anyone can translate to c#
It's very important to drop headers, i had to comment header about Accept and Content-Type and work fine..... of course I did send the token
Dim rest As WebClient = New WebClient()
rest.Headers.Add(HttpRequestHeader.Authorization, "Bearer " & Token)
'rest.Headers.Add(HttpRequestHeader.Accept, "application/json")
'rest.Headers.Add(HttpRequestHeader.ContentType, "application/json")
result = System.Text.Encoding.UTF8.GetString(rest.UploadValues(host_api & uri, "DELETE", New NameValueCollection()))

Categories