I'm relatively new to web interactions with C# and I'm having some trouble making a POST request to upload a file using an API. The API only accepts the files as part of a multipart/form-data section in the body. At other's suggestions I've been trying to use RestSharp to do this, but I can't seem to get the file itself into the POST. Chunks of code derived from Postman suggested code - where the POST works.
I've tried a few things. This chunk resulted in a POST going through with the correct parameter in the body, but no file was included.
var client = new RestClient(postURL);
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", string.Format("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"upfile\"; filename=\"{0}\"\r\nContent-Type: application/xml\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"overwrite\"\r\n\r\ntrue\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", xmlPath), ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
string test = response.Content.ToString();
I also tried some variations of AddFile - physical file path, byte array, and byte array with content type = application/xml. With these iterations, I was able to get a file to post, but the overwrite parameter wasn't coming through correctly to force a file overwrite.
var client = new RestClient(postURL);
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
// The different part below
request.AddFile("upfile", #xmlPath);
request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"overwrite\"\r\n\r\ntrue\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
string test = response.Content.ToString();
*note: I'm using an older version of RestSharp (105.2.3) to be compatible with .Net 4.0 (stuck with it in this case).
Any ideas as to what I'm doing wrong here?
Figured it out after sleeping on it, was really simple in the end. All of the extra webkit and multipart stuff that was throwing me for a loop is entirely unnecessary - autogenerated code from Postman is overly complicated it seems.
var client = new RestClient(postURL);
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
request.AddFile("upfile", #xmlPath);
request.AddParameter("overwrite", "true", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
string test = response.Content.ToString();
Related
Good morning, I'm retrieving an authorization token using RestSharp, but instead of returning a Token, it returns an html page:
var client = new RestClient("https://iam.efatura.cv/auth/realms/taxpayers/ protocol/openid- connect/auth"); var request = new RestRequest(Method.POST); request.AddHeader("grant_type", "authorization_code"); request.AddHeader("content-type", "application/x-www-form-urlencoded"); request.AddHeader("accept", "application/json"); request.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials&client_id=adadasdasdasdasda& scope=openid&clientSecretasdadsdadasdasdasdasdasdasdasasd& redirect_uri=https://iam.efatura.cv/auth/realms/taxpayers", ParameterType.RequestBody); IRestResponse response = client.Execute(request); Token=response.Content;
I am using C# winform on Visual Studio 2019 and using RestSharp.
I have tested WEBAPI function on POSTMAN with correct output.
So i try to implement on C# Winform.
I dump POSTMAN code (C# Restsharp) as following:
var client = new RestClient("http://192.168.2.10:88/en/product/ajax_api_getProductInfoBatch");
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Connection", "keep-alive");
request.AddHeader("Content-Length", "21");
request.AddHeader("Accept-Encoding", "gzip, deflate");
request.AddHeader("Host", "192.168.2.10:88");
request.AddHeader("Postman-Token", "f1ff99c7-dc02-40cb-b87a-
a046cf106a96,e2b7d88d-cfc9-4c99-8117-ec48398e56ed");
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Accept", "*/*");
request.AddHeader("User-Agent", "PostmanRuntime/7.18.0");
request.AddParameter("undefined", "{\n \"Item No\":\"3101\"\n}",
ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
and i revised
request.AddParameter("undefined", "{\n \"Item No\":\"3101\"\n}"
to
request.AddParameter("application/json", "{\"Item No\":\"3101\"}", ParameterType.RequestBody);
Therefore, the full code will be
private void Button1_Click(object sender, EventArgs e)
{
var client = new RestClient("http://192.168.2.10:88/en/product/ajax_api_getProductInfoBatch");
var request = new RestRequest(Method.GET);
//request.AddHeader("cache-control", "no-cache");
//request.AddHeader("Connection", "keep-alive");
//request.AddHeader("Content-Length", "22");
//request.AddHeader("Accept-Encoding", "gzip, deflate");
//request.AddHeader("Host", "192.168.2.10:88");
//request.AddHeader("Postman-Token", "86e877f8-5755-4e57-960a-eaa78b1e8b6c,da863548-65e0-4053-9cb3-b5760da94165");
//request.AddHeader("Cache-Control", "no-cache");
//request.AddHeader("Accept", "*/*");
//request.AddHeader("User-Agent", "PostmanRuntime/7.18.0");
//request.AddHeader("Content-Type", "text/plain");
request.AddParameter("application/json", "{\"Item No\":\"3101\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
var content = response.Content;
textBox1.Text = content;
}
but it is still output "No JSON object could be decoded" after GET request.
Anyone share your experience will be appreciated.
or there are other ways to do GET/POST on C#.
thanks.!
You can use httpclient and pass parameters as stringcontent and type should be application/json for stringcontent.
This is for post request
var client = new RestClient("https://seller.digikala.com/Account/Login");
var request = new RestRequest(Method.POST);
request.AddHeader("postman-token", "0e4d8dba-29da-0b26-1b43-1bf974e9b5de");
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
IRestResponse response = client.Execute(request);
I can send request successfully and login to site in postman, but I can't do it in VS. This is my code in VS:
var client = new RestClient("https://seller.digikala.com/Account/Login");
var request = new RestRequest(Method.POST);
request.AddParameter("IsPersistent", true, ParameterType.GetOrPost);
request.AddParameter("Password", "myPass", ParameterType.GetOrPost);
request.AddParameter("UserName", "myUsername", ParameterType.GetOrPost);
request.AddParameter("returnUrl", "/Account/Login", ParameterType.GetOrPost);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
IRestResponse response = client.Execute(request);
but I get "unauthorized" message (401) in VS
you can use PostMan Auto C# Code generator
I believe your issue is that you're adding things that should be part of the body as parameters (based on the screenshot from PostMan showing these items as part of the body). This is untested but may work for you.
var client = new RestClient("https://seller.digikala.com/Account/Login");
var request = new RestRequest(Method.POST);
request.AddBody(new
{
IsPersistant = true,
Password = "myPass",
UserName = "myUsername",
returnUrl = "/Account/Login"
});
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
IRestResponse response = client.Execute(request);
You probably need to do a GET of the page first, then when making then POST reflect back all cookies received during the GET (if that RestClient of yours doesn't do that automatically).
Login pages typically add a cookie during GET and expect that cookie during POST to prevent XSRF (this involves including that same token as a form's hidden field, although the XSRF token is apparently not present in your Postman payload). It also wouldn't surprise me that some cookie-based sessionID filter is blocking you even before your request hits the login controller/middleware. In any case, doing the GET first and then reflecting the cookies in POST should work.
Question: How to upload an XML file using multipart/form-data with Restsharp?
Problem:
I'm using Peppol for sending invoices using the Codabox API.
I want to upload an xml to the rest service.
The rest service itself is under control by the provider Codabox.
I have 2 methods provided who I expect to do the same.
First of all with Postman and httpclient, all the things works fine.
I want to get the same from the httpclient method working using the restsharp way.
RestSharp version: 106.2.1
Error message with Restsharp
response = "StatusCode: BadRequest, Content-Type: application/json,
Content-Length: -1)" Content = "{\"file\":[\"No file was
submitted.\"]}"
For realizing this I have an X-Software-Company key in the header, providing a valid xml file that I send using form-data (multipart/form-data) and my authentication credentials.
Expected solution:
I want to get the Restsharp method working and why it now doesn't work.
So the Restsharp method I provided need to do the same as the httpclient method I provided.
What I have tried:
Restsharp method: ==> here is the problem
public void TestUpload()
{
byte[] fileBytes = File.ReadAllBytes(#"C:\temp\test.xml");
var client = new RestClient("url for the rest call");
var request = new RestRequest(Method.POST);
request.AlwaysMultipartFormData = true;
request.Credentials = new NetworkCredential("username", "password");
request.AddHeader("X-Software-Company", "software key");
request.AddHeader("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
request.AddFile("file", #"C:\temp\test.xml");
//request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
//request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"file\"; filename=\"C:\\temp\\test.xml\"\r\nContent-Type: false\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
}
HttpClient method: ==> it works fine
public void TestUploadHttpClient()
{
byte[] fileBytes = File.ReadAllBytes(#"C:\temp\test.xml");
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "credentials");
httpClient.DefaultRequestHeaders.Add("X-Software-Company", "software key");
using (var content = new MultipartFormDataContent("boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"))
{
content.Add(new StreamContent(new MemoryStream(fileBytes)), "file", "test.xml");
using (var message = httpClient.PostAsync("url for the rest call", content).Result)
{
var input = message.Content.ReadAsStringAsync().Result;
}
}
}
}
Postman generated code:
If I do the request by Postman there is no problem, if I check the Restsharp code generated by postman it gives me:
var client = new RestClient("url for the rest call");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Basic credentials");
request.AddHeader("Content-Type", "multipart/form-data");
request.AddHeader("X-Software-Company", "software key");
request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"file\"; filename=\"C:\\temp\\test.xml\"\r\nContent-Type: false\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
I have exactly the code tested generated from postman but it doesn't work.
EDIT 2018-03-19:
Possible issue in RestSharp: Added files not being recieved #1079
Temporary solution:
I'm using RestSharp version v105.2.3 then it works like a charm.
Have anyone an idea why the restsharp method does not work and how to solve that?
Try to put the content type parameter in the AddFile method, like this:
request.AddFile("file", #"C:\temp\test.xml", "application/octet-stream");
I have the following JSON string that is passed into my c# code as a string parameter - AddLocation(string locationJSON):
{"accountId":"57abb4d6aad4","address":{"city":"TEST","country":"TEST","postalCode":"TEST","state":"TEST","street":"TEST"},"alternateEmails":[{"email":"TEST"}],"alternatePhoneNumbers":[{"phoneNumber":"TEST"}],"alternateWebsites":[{"website":"TEST"}],"auditOnly":false,"busName":"593163b7-a465-43ea-b8fb-e5b967d9690c","email":"TEST EMAIL","primaryKeyword":"TEST","primaryPhone":"TEST","rankingKeywords":[{"keyword":"TEST","localArea":"TEST"}],"resellerLocationId":"5461caf7-f52f-4c2b-9089-2ir8hgdy62","website":"TEST"}
I'm trying to add the JSON to a RestSharp POST request like this but it's not working:
public string AddLocation(string locationJSON)
{
var client = new RestClient(_authorizationDataProvider.LocationURL);
var request = new RestRequest(Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Authorization", _authorizationResponse.Token);
...
request.AddJsonBody(locationJSON);
var response = client.Execute(request);
}
The response comes back as "Bad Request". Here is what I get if I inspect the response in the debugger:
{"code":"invalid_json","details":{"obj.address":[{"msg":["error.path.missing"],"args":[]}],"obj.rankingKeywords":[{"msg":["error.path.missing"],"args":[]}],"obj.alternatePhoneNumbers":[{"msg":["error.path.missing"],"args":[]}],"obj.busName":[{"msg":["error.path.missing"],"args":[]}],"obj.accountId":[{"msg":["error.path.missing"],"args":[]}],"obj.alternateEmails":[{"msg":["error.path.missing"],"args":[]}],"obj.alternateWebsites":[{"msg":["error.path.missing"],"args":[]}],"obj.email":[{"msg":["error.path.missing"],"args":[]}],"obj.primaryKeyword":[{"msg":["error.path.missing"],"args":[]}],"obj.auditOnly":[{"msg":["error.path.missing"],"args":[]}]}}
I have inspected the request parameters after calling AddJsonBody and the value appears to be including the escape sequence for double quotes - which seems to be the issue.
{\"accountId\":\"57abb4d6aad4def3d213c25d\",\"address\":{\"city\":\"TEST\",\"country\":\"TEST\",\"postalCode\":\"TEST\",\"state\":\"TEST\",\"street\":\"TEST\"},\"alternateEmails\":[{\"email\":\"TEST\"}],\"alternatePhoneNumbers\":[{\"phoneNumber\":\"TEST\"}],\"alternateWebsites\":[{\"website\":\"TEST\"}],\"auditOnly\":false,\"busName\":\"84e7ef98-7a9f-4805-ab45-e852a4b078d8\",\"email\":\"TEST EMAIL\",\"primaryKeyword\":\"TEST\",\"primaryPhone\":\"TEST\",\"rankingKeywords\":[{\"keyword\":\"TEST\",\"localArea\":\"TEST\"}],\"resellerLocationId\":\"06b528a9-22a6-4853-8148-805c9cb46941\",\"website\":\"TEST\"}
so my question is how do I add a json string to the request body?
I've ran into this problem as well. Try something like this instead of AddJsonBody.
request.AddParameter("application/json", locationJSON, ParameterType.RequestBody);
This should work:
request.AddParameter("application/json; charset=utf-8", JsonConvert.SerializeObject(yourObject), ParameterType.RequestBody);
If you directly add the serialized object, the problem is the Json convert is adding "\" before each ".
I have tried like this and it working fine, Add Bearer with token
request.AddHeader("cache-control", "no-cache");
request.AddHeader("authorization", "Bearer " + "your token key");
request.AddHeader("accept", "application/json");