I have the following python code how to post a picture through webservice:
product_image = requests.post(
'https://client.planorama.com/tapi/v1/product_image/',
data={ 'product_id': 1784682 },
files={ "file": open(my_image.jpg, 'rb') }
)
Can anyone help me to do the same thing in C#,
Multipart Form Post in C# includes a simple C# class using HttpWebRequest with a provided (working) example.
We are rather spoiled with the requests library in python.
Are you running .NET 4 or 4.5? If so, take a look at Joshcodes answer to Sending Files using HTTP POST in c# - it uses Microsoft.Net.Http which is by far the best HTTP library in the .NET world these days.
UPDATE: I haven't checked this for accuracy yet, but it could go something like this:
static HttpResponseMessage UploadFileWithParam(string requestUri, string fileName, string key1, string val1)
{
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
content.Add(new StringContent(val1), key1);
var fileContent = new StreamContent(File.OpenRead(fileName));
fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
content.Add(fileContent);
return client.PostAsync(requestUri, content).Result;
}
}
}
// UploadFileWithParam("http://example.com", #"c:\...", "param1", "value1").Dump();
Related
I am updating some old C# code to use HttpClient instead of WebClient. As part of this, I need to upload a byte array of a file to an api.
With WebClient, this worked perfectly fine
byte[] data = GetMyData();
using (var client = new WebClient())
{
//set url, headers etc
var r = client.UploadData(url, "PUT", data);
}
With HttpClient, I've tried various methods, such as
byte[] data = GetMyData();
using (var client = new HttpClient())
{
//set url, headers etc
var r = await client.PutAsync(url, new ByteArrayContent(data));
}
I've also tried different ways of using Multipart data that I found Googling around, but the server does not accept anything I've tried. I don't have a lot of documentation on the server API, I only know that the WebClient way has worked well for many years. Is there a way to recreate the WebClient.UploadData behavior with HttpClient?
Thanks to the commenters for putting me on the right track. The Content-Type headers were not being set correctly for the HttpClient way, by putting it on the actual content. code below.
byte[] data = GetMyData();
using (var client = new HttpClient())
{
//set url, headers etc
var content = new ByteArrayContent(data);
content.Headers.ContentType = new MediaTypeWithQualityHeaderValue(contentType);
var r = await client.PutAsync(url, content);
}
Here's a generic cURL command to copy a csv file from a server to c:\temp.
curl.exe --data "ARG1=value&ARG2=value" "https://some.server.com/data.csv" > "c:\temp\data.csv"
How would you code this a synchronous method in C# using a post method and TLS 1.2?
byte[] data;
using (WebClient client = new WebClient()) {
data = client.DownloadData("https://some.server.com/data.csv?arg1=value&ARG2=value");
}
File.WriteAllBytes(#"c:\temp\data.csv", data);
After some fiddling found this to work:
using System.Net.Http;
...
var values = new Dictionary<string, string>() { { "arg1", "value1" }, { "arg2", "value2" } };
var content = new FormUrlEncodedContent(values);
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; // enable TLS 1.2
HttpResponseMessage responseMsg = new HttpClient().PostAsync(#"http://some.server.com/data.csv", content).Result;
if (responseMsg.StatusCode != System.Net.HttpStatusCode.OK) throw new Exception("err msg");
File.WriteAllText(#"c:\temp\data.csv", responseMsg.Content.ReadAsStringAsync().Result);
...
This code worked for me (I can't show the actual site). The site in question is a data vendor who used to accept simple HTTP GET requests but is now switching to POST with SSL and TSL 1.2 in order to comply with EU rules.
I am not claiming that this code is robust, thread safe, or anything like that. Just that I got it working. So that's a start.
I'm a novice programmer and I'm trying to put a small Discord bot together for a server. After spending a good hour or two trying to figure out how to use the API from https://icanhazdadjoke.com/api I have given up and have come to ask for help.
At the moment I'm using
public static async Task<string> GetRequest(string url)
{
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.GetAsync(url))
{
using (HttpContent content = response.Content)
{
string myContent = await content.ReadAsStringAsync();
var obj = JObject.Parse(myContent);
var ret = (string)obj["joke"];
Console.WriteLine("joke: {0}", ret);
return ret;
}
}
}
}
The code is looking for content with the label "fact" when the joke API uses "joke"; you can't just use the same code across differing APIs, particularly when they have structured content like JSON.
Try changing
var ret = (string)obj["fact"]
to:
var ret = (string)object["joke"]
I would recommend you read: What is JSON? over at W3.
And be sure to always pay attention to the API documentation:
Fetching a random joke as JSON:
$ curl -H "Accept: application/json" https://icanhazdadjoke.com/
{
"id": "R7UfaahVfFd",
"joke": "My dog used to chase people on a bike a lot. It got so bad I had to take his bike away.",
"status": 200
}
You can see the JSON structure, and the "joke" field.
Before I upgraded to the newest .NetCore I was able to run the HttpWebRequest, add the headers and content Type and pull the stream of the JSON file from Twitch. Since the upgrade this is not working. I receive a Web Exception each time I go to get the response Stream. Nothing has changed with twitch because it still works with the old Bot. The old code is below:
private const string Url = "https://api.twitch.tv/kraken/streams/channelname";
HttpWebRequest request;
try
{
request = (HttpWebRequest)WebRequest.Create(Url);
}
request.Method = "Get";
request.Timeout = 12000;
request.ContentType = "application/vnd.twitchtv.v5+json";
request.Headers.Add("Client-ID", "ID");
try
{
using (var s = request.GetResponse().GetResponseStream())
{
if (s != null)
using (var sr = new StreamReader(s))
{
}
}
}
I have done some research and found that I may need to start using either an HttpClient or HttpRequestMessage. I have tried going about this but when adding headers content type the program halts and exits. after the first line here: (when using HttpsRequestMessage)
request.Content.Headers.ContentType.MediaType = "application/vnd.twitchtv.v5+json";
request.Content.Headers.Add("Client-ID", "rbp1au0xk85ej6wac9b8s1a1amlsi5");
You are trying to add a ContentType header, but what you really want is to add an Accept header (your request is a GET and ContentType is used only on requests which contain a body, e.g. POST or PUT).
In .NET Core you need to use HttpClient, but remember that to correctly use it you need to leverage the use of async and await.
Here it is an example:
using System.Net.Http;
using System.Net.Http.Headers;
private const string Url = "https://api.twitch.tv/kraken/streams/channelname";
public static async Task<string> GetResponseFromTwitch()
{
using(var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.twitchtv.v5+json"));
client.DefaultRequestHeaders.Add("Client-ID", "MyId");
using(var response = await client.GetAsync(Url))
{
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync(); // here we return the json response, you may parse it
}
}
}
The current project I am working on requires a 2 way communication from the bot to my website.
Supposing the example URL is www.example.com/foobar.php or something, can you explain me how to POST and GET data from there?
Thanks a lot.
P.S. - Using webclient right?
I'd suggest using RestSharp. It's a lot easier than using WebClient, and gives you a lot more options:
var client = new RestClient("http://www.example.com/");
//to POST data:
var postRequest = new RestRequest("foo.php", Method.POST);
postRequest.AddParameter("name", "value");
var postResponse = client.Execute(postRequest);
//postResponse.Content will contain the raw response from the server
//To GET data
var getRequest = new RestRequest("foo.php", Method.GET);
getRequest.AddParameter("name", "value");
var getResponse = client.Execute(getRequest);
Yes, you can use WebClient:
using (WebClient client = new WebClient())
{
NameValueCollection nvc = new NameValueCollection()
{
{ "foo", "bar"}
};
byte[] responseBytes = client.UploadValues("http://www.example.com/foobar.php", nvc);
string response = System.Text.Encoding.ASCII.GetString(responseBytes);
}
You can use WebClient
Look up method UploadString and DownloadString