RestSharp doesn't UTF-8 Encode the Request - c#

I'm trying to POST a request with one lonely parameter, as such:
var client = new RestClient("http://www.fluff.com");
var request = new RestRequest("whatever", Method.POST);
request.AddParameter("param", "Оксана");
client.Execute(request);
This results in the following request, notice the bunch of encoded question marks:
POST http://www.fluff.com/whatever HTTP/1.1
Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml
User-Agent: RestSharp/105.0.1.0
Content-Type: application/x-www-form-urlencoded
Host: www.fluff.com
Content-Length: 24
Accept-Encoding: gzip, deflate
param=%3F%3F%3F%3F%3F%3F
Imagine the sadness when the receiver gets those question marks..
How do I make RestSharp properly encode the body as UTF-8, or how do I send the request in a RestSharp friendly way so that she doesn't garble the data?

Christer, that's standard encoding for Content-Type: application/x-www-form-urlencoded, which uses ISO-8859-1 as a default. If you specifically want to tell the server to expect UTF-8, you can add ; charset=UTF-8 at the end Content-Type: application/x-www-form-urlencoded ; charset=UTF-8. But then it's your responsibility to make sure the data you post is really encoded in UTF-8.
Or if you want to do it in "application/json", you can set the content type in this way (I got this from http://itanex.blogspot.com/2012/02/restsharp-and-advanced-post-requests.html):
request.AddHeader("Accept", "application/json");
request.Parameters.Clear();
request.AddParameter("application/json", strJSONContent, ParameterType.RequestBody);
You could also use multipart/form-data: <form action="YOUR_ACTION_NAME_HERE" method="post" enctype="multipart/form-data">

Related

.net httpclient Charset encoding is different than Fiddler

I'm currently working with an api that requires me to send a json in UTF-32 encoding format.
I am using HttpClient lib but it does not encode my json the way Fiddler does so the server returns error. I've googled for hours but without success, anyway here's my raw request (Fiddler):
POST http://example.com/ HTTP/1.1
Content-Type: application/json; charset=utf-32
Host: example.com
Content-Length: 92
Expect: 100-continue
Connection: Keep-Alive
{"jsonKey":"JsonValue"}
The encoded content looks like this:
and here's my simple C# request:
using(HttpClient client = new HttpClient(new HttpClientHandler() { Proxy = new WebProxy("127.0.0.1:8080") }))
{
_ = await client.PostAsync("http://example.com", new StringContent("{\"jsonKey\":\"JsonValue\"}", Encoding.UTF32, "application/json")).ConfigureAwait(false);
}
C#'s content looks like this:

Unsupported Media Type when consuming text/plain

I receive the following response when trying to consume text/plain:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
"title": "Unsupported Media Type",
"status": 415,
"traceId": "|b28d0526-4ca38d2ff7036964."
}
Controller definition:
[HttpPost]
[Consumes("text/plain")]
public async Task<IActionResult> PostTrace([FromBody]string body)
{ ... }
HTTP message:
POST /api/traces HTTP/1.1
Content-Type: text/plain
User-Agent: PostmanRuntime/7.19.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 37d27eb6-92a0-4a6a-8b39-adf2c93955ee
Host: 0.0.0.0:6677
Accept-Encoding: gzip, deflate
Content-Length: 3
Connection: keep-alive
I am able to consume JSON or XML just fine. What am I missing?
Reference: Accepting Raw Request Body Content in ASP.NET Core API Controllers:
Unfortunately ASP.NET Core doesn't let you just capture 'raw' data in any meaningful way just by way of method parameters. One way or another you need to do some custom processing of the Request.Body to get the raw data out and then deserialize it.
You can capture the raw Request.Body and read the raw buffer out of that which is pretty straight forward.
The easiest and least intrusive, but not so obvious way to do this is to have a method that accepts POST or PUT data without parameters and then read the raw data from Request.Body:
[HttpPost]
[Route("api/BodyTypes/ReadStringDataManual")]
public async Task<string> ReadStringDataManual()
{
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
return await reader.ReadToEndAsync();
}
}
Request:
POST http://localhost:5000/api/BodyTypes/ReadStringDataManual HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/plain
Host: localhost:5000
Content-Length: 37
Expect: 100-continue
Connection: Keep-Alive
Windy Rivers with Waves are the best!

Content type in call to web service

Please correct me if I'm wrong in defining contet type:
Content-Type: application/json; charset=utf-8
{"my_id":"975","my_a_id":"Test66","param":"4","amount":"66"}
and
Content-Type: application/x-www-form-urlencoded
my_id=123&my_a_id=Test66&param=4&amount=66
What other content types might be?
What content type supports RESTLet NetSuite services?
I have POST to web service:
POST https://some.netsuite.uri?deploy=1 HTTP/1.1
Authorization: NLAuth nlauth_account=3624292_SB3, nlauth_email=xduh31#gmail.com, nlauth_signature=Pass987654, nlauth_role=3
Accept: application/json
Content-Type: application/json; charset=utf-8
Host: rest.eu1.netsuite.com
Cookie: JSESSIONID=**************************************; lastUser=1234567_SB9_1282_3; NS_ROUTING_VERSION=LAGGING; NS_VER=2017.1.0
Content-Length: 69
Expect: 100-continue
{"my_id":"975","my_a_id":"Test66","param":"4","amount":"66"}
Is it good that in URL I have something like x-www-form-urlencoded - ?deploy=1
https://some.netsuite.uri?deploy=1
and data is json style:
{"my_id":"975","my_a_id":"Test66","param":"4","amount":"66"}
UPD
I got answer that I suppose should return JSON data:
HTTP/1.1 200 OK
Date: Sat, 03 Jun 2017 06:21:46 GMT
Server: Apache
Cache-Control: No-Cache
Pragma: No-Cache
Content-Length: 41
Expires: 0
Edge-Control: no-store
X-N-OperationId: 486c2d20-099d-446b-9788-4816db59a1fd
Set-Cookie: .......................; path=/
NS_RTIMER_COMPOSITE: 1688996695:706172746E6572733030312E70726F642E6475622E6E65746C65646765722E636F6D:80
P3P: CP="CAO PSAa OUR BUS PUR"
Vary: User-Agent
Content-Type: application/json; charset=utf-8
org.mozilla.javascript.Undefined#54b896b0
But this answer not looks like JSON?
One problem might be your URL. Have you tried changing
https://some.netsuite.uri&deploy=1
to
https://some.netsuite.uri?deploy=1
Edit:
Also, your Accept header says you are looking for an application/json response, is that what the server is returning?
You can find supported content types in NS Help Center:
RESTlets support JSON and plain text content types for input and
output. For each RESTlet, output content type is the same as input
content type.
You must set the content type in the HTTP Content-Type header. You can
use the following values to specify the input/output content type for
a RESTlet:
application/json
text/plain
If you specify a content type other than JSON or text, a 415 error is
returned with the following message:
Invalid content type. You can only use application/json or text/plain
with RESTlets.
Documentation
Besides that the issue in the url mentioned by shazmodan, the script Id is missing. Below is an example of a valid restlet url:
https://rest.netsuite.com/app/site/hosting/restlet.nl?deploy=1&script=1
You can pass additional parameters in the url:
https://rest.netsuite.com/app/site/hosting/restlet.nl?deploy=1&script=1&my_id=123&my_a_id=Test66&param=4&amount=66
or in the request body if you are using POST and PUT methods but it needs to be a valid JSON. But the Content Type must always be application/json or text/plain.

How to read and process a HTTP POST

I have a HTTP handler which receives a HTTP POST. HTTP POST message with header is -
POST /ibe/example.ashx HTTP/1.1
Content-Length: 41
Content-Type: application/x-www-form-urlencoded; text/html; charset=GBK
Host: 202.177.46.142
User-Agent: Mozilla/4.0
param1=value1&param2=value2&param3=value3
Handler in my code is -
var V1 = context.Request["param1"];
var V2 = context.Request["param2"];
But values returning are null
if it's a post I think you'd want to use a stream reader to get the body, then deserialize if needed.

multipart/form-data + Sockets = Server not Responding

I'm using my own HTTP wrapper using sockets. So far everything works except multipart/form-data POST. When I send the data to server, it simply doesn't respond, so I'm guessing I'm missing something in my POST like I would need "\r\n\r\n" for regular requests.
This is my request:
POST /getproxies/get.php HTTP/1.1
Host: myhost.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Cookie: sid=UtozR43zQQAtVA2Np0KP_ZLnO0IYwwU1S_Tt4Z3N80wctL;
Connection: Close
Content-Type: multipart/form-data; boundary=---------------------------4664151417711
Content-Length: 411
---------------------------4664151417711
Content-Disposition: form-data; name="proxy_count"
20 proxies
---------------------------4664151417711
Content-Disposition: form-data; name="u"
13
---------------------------4664151417711
Content-Disposition: form-data; name="opt_1"
---------------------------4664151417711
Content-Disposition: form-data; name="opt_2"
GET
---------------------------4664151417711--
When I send the data, the connection is open, like it would be waiting on the server, but server doesn't respond. Any ideas what am I missing here? Thanks
Your boundary isn't matching the one declared on the boundary= part.
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x
Content-Disposition: form-data; name="submit-name"
Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x--
RFC 2046 - Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types:
The Content-Type field for multipart entities requires one parameter,
"boundary". The boundary delimiter line is then defined as a line
consisting entirely of two hyphen characters ("-", decimal value 45)
followed by the boundary parameter value from the Content-Type header
field, optional linear whitespace, and a terminating CRLF.
So I guess this should work:
Content-Type: multipart/form-data; boundary=54472172614771
Content-Length: 47
--54472172614771
Your data
--54472172614771--
Please note the boundary specified in the boundary parameter of the Content-Type header should match the boundary you use in the payload. Also note the boundaries also count towards the Content-Length.

Categories