posting a json using httpClient is not arriving at the server - c#

I have this code:
String json = "{\"name\":\"listFiles\"}";
// Wrap our JSON inside a StringContent which then can be used by the HttpClient class
HttpContent httpContent = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = client.PostAsync(endPoint, httpContent).Result;
response.EnsureSuccessStatusCode();
when this post is done, I can see that server received a call but the content is blank (content size is correct, but it has no data).
I tried to investigate if the httpContent has the json data, but I can not see any data.
Why this code, post blank data to server and why I can not see any data inside httpContent?
How can I extract json back from httpContent, so I can check that it is properly initialized?
where is its content?
Edit1
I checked the server and I am getting this data:
POST /osc/command/execute HTTP/1.1
Content-Type: application/json
Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml
User-Agent: RestSharp/106.2.1.0
Host: 192.168.1.138
Content-Length: 32
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
when I am sending data using restshart library as follow:
var client = new RestClient("http://192.168.1.138/osc/command/execute");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\n \"name\":\"camera.listFiles\"\n}\n", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
when I post the same code using postman, I am getting this on server:
POST /osc/command/execute HTTP/1.1
cache-control: no-cache
Postman-Token: 83ecd3ec-a85d-41a6-ab0e-029ee1690cce
Content-Type: application/json
User-Agent: PostmanRuntime/6.3.2
Accept: */*
Host: 192.168.1.138
accept-encoding: gzip, deflate
content-length: 32
Connection: keep-alive
{
"name":"camera.listFiles"
}
so why there is nothing at the end of packet that I am reading with content that I posted?
Edit 2
I posted the data to "http://httpbin.org/post" and the result that I am getting is:
{
"args": {},
"data": "{\"name\":\"listFiles\"}",
"files": {},
"form": {},
"headers": {
"Accept": "application/json",
"Connection": "close",
"Content-Length": "20",
"Content-Type": "application/json; charset=utf-8",
"Expect": "100-continue",
"Host": "httpbin.org"
},
"json": {
"name": "listFiles"
},
"origin": "91.240.174.154",
"url": "http://httpbin.org/post"
}
I can not see any payload here, but I can see the json with my data in it. The question is that why there is no payload as explained in this document: How are parameters sent in an HTTP POST request?
note1
What I can see is that when I posted to "http://httpbin.org/post", the connection is closed, but when I posted to my server, the connection is keep-alive, what is the difference? Is there any possibility that I am not reading all data from client on server and I should wait for another packet?

I have no reputation to comment on your post (which is where i wanted to place this comment - so please go easy on me regarding down votes). But we had an issue almost exactly the same as yours today. After conferring with a co-worker on this, we were able to get the JSON response in essence by changing your line:
HttpResponseMessage response = client.PostAsync(endPoint, httpContent).Result;
to
var response = client.PostAsync(endPoint, httpContent).Result.Content.ReadAsStringAsync();
That revealed our JSON

Related

Restsharp adds guid to body, how do I remove it?

My code is below, it is very simple. I was trying to match a postman call and it came pretty close, but when I made the call in postman it looks different, specifically restsharp adds a guid around the body that I saw in fiddler. The guide seems to break my calls, how do I remove it?
string url = "https://url/api/";
var client = new RestClient(url);
client.AddDefaultHeader("x-ads-dev", "Key");
var request = new RestRequest("telemetry", Method.Post);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", datapoint, ParameterType.RequestBody);
var response = await client.PostAsync(request);
And here is what Fiddler shows:
POST http://url/api/telemetry HTTP/1.1
Host: api.adsprism.com
x-ads-dev: key
Accept: application/json, text/json, text/x-json, text/javascript, application/xml, text/xml
User-Agent: RestSharp/107.3.0.0
Accept-Encoding: gzip, deflate, br
Content-Type: application/json; boundary="717cb9fd-684d-424e-bd0a-cf6b0bb11bac"
Content-Length: 398
--717cb9fd-684d-424e-bd0a-cf6b0bb11bac
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name="application/json"
[{"entityID":2123,"locationID":33,"data":[{"dateTime":"2020-08-03 23:05:00","reading":0,"flags":0,"quality":15,"ignore":false},{"dateTime":"2020-09-27 03:10:00","reading":0,"flags":0,"quality":15,"ignore":false}]}]
--717cb9fd-684d-424e-bd0a-cf6b0bb11bac--
The --717cb9fd-684d-424e-bd0a-cf6b0bb11bac-- guid is not there in the fiddler postman request and it seems to be causing a bad request error from restsharp. So how do I make restsharp not generate it?
EDIT: Added postman fiddler to show the difference.
POST http://api.url/api/telemetry HTTP/1.1
x-ads-dev: key
Content-Type: application/json
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: 5f186e6d-cad0-482c-b7b8-a50559f24b87
Host: api.adsprism.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 513
[
{
"entityID": 2123,
"locationID": 33,
"data": [
{
"dateTime": "2020-08-03 23:05:00",
"reading": 0,
"flags": 0,
"quality": 0,
"ignore": true
},
{
"dateTime": "2020-09-27 03:10:00",
"reading": 0,
"flags": 0,
"quality": 0,
"ignore": true
}
]
}
]
Reading the docs can help.
const string url = "https://url/api/";
var client = new RestClient(url);
client.AddDefaultHeader("x-ads-dev", "Key");
var request = new RestRequest("telemetry", Method.Post);
request.AddStringBody(datapoint, DataType.Json);
var response = await client.PostAsync(request);

Sending post request multipart form data. Error from some microsoft service "Line length limit 100 exceeded"

This data is sent from Postman and it works:
This is a postman request which passes with a 200 status:
POST /api/upload HTTP/1.1
Host: api.test.contoso.se
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Authorization: Basic 123
User-Agent: PostmanRuntime/7.13.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 089af753-fa12-46c4-326f-dfc39c36faab,c5977145-ece3-4b53-93ff-057788eb0dcf
Host: api.test.contoso.se
accept-encoding: gzip, deflate
content-length: 18354
Connection: keep-alive
cache-control: no-cache
Content-Disposition: form-data; name="Lang"
SV
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="File"; filename="/C:/Users/file.docx
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="Login"
ABC
This is my request from NodeJs via Axios:
const form_data = new FormData();
form_data.append("File", fs.createReadStream(pathToFile));
form_data.append('Login', alias.toUpperCase());
console.log(form_data); // se output down
const request_config = {
headers: {
"Authorization": "Basic 123",
"Content-Type": `multipart/form-data; boundary=${form_data._boundary}`
},
data: form_data
};
console.log(form_data):
FormData {
_overheadLength: 540,
_valueLength: 13,
_valuesToMeasure:
[ ReadStream {
_readableState: [ReadableState],
readable: true,
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
path:
'/Users/qq/test.docx',
fd: null,
flags: 'r',
mode: 438,
start: undefined,
end: Infinity,
autoClose: true,
pos: undefined,
bytesRead: 0,
closed: false,
emit: [Function] } ],
writable: false,
readable: true,
dataSize: 0,
maxDataSize: 2097152,
pauseStreams: true,
_released: false,
_streams:
[ '----------------------------610001147909085905792533\r\nContent-Disposition: form-data; name="File"; filename="test.docx"\r\nContent-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document\r\n\r\n',
DelayedStream {
source: [ReadStream],
dataSize: 0,
maxDataSize: Infinity,
pauseStream: true,
_maxDataSizeExceeded: false,
_released: false,
_bufferedEvents: [Array],
_events: [Object],
_eventsCount: 1 },
[Function: bound ],
'----------------------------610001147909085905792533\r\nContent-Disposition: form-data; name="Login"\r\n\r\n',
'abc',
[Function: bound ] ],
_currentStream: null,
_insideLoop: false,
_pendingNext: false,
_boundary: '--------------------------610001147909085905792533
The error I get from ASP server: Line length limit 100 exceeded
What am I missing in my request?
According to these two github issues:
https://github.com/aspnet/AspNetCore/issues/2939
https://github.com/aspnet/AspNetCore/issues/3724
The issue is caused by a failure to use the correct line endings. I can't tell from your code exactly where the issue is occuring, but it should be fairly straightforward to debug it.
You need to use a proxy - I find Fiddler to be very good. Capture the request from Postman and from your Client and compare them. You may need to drop the whole request into an editor like Notepad++ to be able to view the non-printing characters.
Once you find the issue, it should be straightforward to amend to add or remove \r as appropriate.
The code below setup a HTTP server at localhost:3000, and for all incoming requests, the server dumps the raw request body.
Try posting your request to localhost:3000 from both Postman and Nodejs, and compare the difference.
require('http').createServer((req, res) => {
req.on("data", _ => _)
.on("end" , _ => res.end(req.socket.rawBody));
}).on('connection', socket => {
socket.rawBody = "";
socket.on('data', data => socket.rawBody += data.toString());
}).listen(3000);
This is the sample output
POST / HTTP/1.1
Authorization: Basic QUJDOkFCQw==
User-Agent: PostmanRuntime/7.15.0
Accept: */*
Cache-Control: no-cache
Host: localhost:3000
accept-encoding: gzip, deflate
content-type: multipart/form-data; boundary=--------------------------540608501697240762060297
content-length: 268
Connection: keep-alive
----------------------------540608501697240762060297
Content-Disposition: form-data; name="Lang"
SV
----------------------------540608501697240762060297
Content-Disposition: form-data; name="Login"
ABC
----------------------------540608501697240762060297--
Hope this will help you debug the problem.

use HttpClient to set the Content-Type to "application/json" and add object to the body

I'm trying to create the following post using HttpClient, using postman its working correctly but I cant seem to replicate it in code. I need to set the header Content-Type to application/json and have an object in the body of the post.
POST https://mycompanyurl.com/authenticate
HEADERS
Key: Content-Type, Value: application/json
BODY
{
"username": "someusername",
"password": "somepassword"
}
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://companyurl.com");
var serializedObject = JsonConvert.SerializeObject(
new {username = "username", password = "password" });
var request = new HttpRequestMessage(HttpMethod.Post, "authenticate");
request.Content = new StringContent(serializedObject, Encoding.UTF8,"application/json");
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
}
Using the reverse proxy in fidder I can capture the raw call from postman which works, the rest api returns a result as expected:
POST http://127.0.0.1:8888/v1/authenticate HTTP/1.1 Content-Type: application/json;charset=UTF-8 cache-control: no-cache Postman-Token: 4db8f2dd-cbf0-413c-ad5b-20af0543a31d User-Agent: PostmanRuntime/7.6.0 Accept: / Host: 127.0.0.1:8888 accept-encoding: gzip, deflate content-length: 87 Connection: keep-alive
{"username":"username","password":"password"}
My call from HttpClient and using fiddler is below, This does not work, returns 200 but its not working correctly, data is not being returned, I cant see anything differences in the payload that will make the rest api not respond as expected.
POST http://127.0.0.1:8888/v1/authenticate HTTP/1.1 Content-Type: application/json; charset=utf-8 Host: 127.0.0.1:8888 Content-Length: 87 Expect: 100-continue Connection: Keep-Alive
{"username":"username","password":"password"}
The logic below should generate the same working request signature provided in your example (which was posted as an Answer, please edit your Question instead), and therefore should work:
var clientHandler = new HttpClientHandler
{
AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate,
AllowAutoRedirect = false
};
using (var client = new HttpClient(clientHandler, true))
{
client.BaseAddress = new Uri("http://127.0.0.1:8888/v1/");
client.DefaultRequestHeaders.Add("cache-control", "no-cache");
client.DefaultRequestHeaders.Add("Postman-Token", "db8f2dd-cbf0-413c-ad5b-20af0543a31d");
client.DefaultRequestHeaders.Add("User-Agent", "PostmanRuntime/7.6.0");
client.DefaultRequestHeaders.Add("Accept", "*/*");
client.DefaultRequestHeaders.ExpectContinue = false;
var serializedObject = JsonConvert.SerializeObject(
new { username = "username", password = "password" }
);
var request = new HttpRequestMessage(HttpMethod.Post, "authenticate")
{
Content = new StringContent(serializedObject, Encoding.UTF8, "application/json")
};
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
}
It will create the following request:
POST http://127.0.0.1:8888/v1/authenticate HTTP/1.1
cache-control: no-cache
Postman-Token: db8f2dd-cbf0-413c-ad5b-20af0543a31d
User-Agent: PostmanRuntime/7.6.0
Accept: */*
Content-Type: application/json; charset=utf-8
Host: 127.0.0.1:8888
Content-Length: 45
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
{"username":"username","password":"password"}
Hope this helps.

how to post data to url using c#

i want send this data using post method in c#
POST https://lyncweb.contoso.com/ucwa/oauth/v1/applications/103...740/onlineMeetings/ myOnlineMeetings HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer cwt=AAEB...buHc
X-Ms-Origin: http://localhost
X-Requested-With: XMLHttpRequest
Referer: https://lyncweb.contoso.com/Autodiscover/XFrame/XFrame.html
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0;.NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; InfoPath.3)
Host: lyncweb.contoso.com
Content-Length: 185
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
{
"attendanceAnnouncementsStatus":"Disabled",
"description":"hey guys let's do a musical!",
"subject":"holiday party",
"attendees": ["sip:Chris#contoso.com","sip:Alex#contoso.com"],
"leaders": []
}
please help me to write code in c# desktop application.
You can use Restsharp it is an lib that you can get from Nuget. very easy to use:
here is an example:
var client = new RestClient("http://example.com");
// client.Authenticator = new HttpBasicAuthenticator(username, password);
var request = new RestRequest("resource/{id}", Method.POST);
request.AddParameter("name", "value"); // adds to POST or URL querystring based on Method
request.AddUrlSegment("id", "123"); // replaces matching token in request.Resource
// easily add HTTP Headers
request.AddHeader("header", "value");
// add files to upload (works with compatible verbs)
request.AddFile(path);
// execute the request
IRestResponse response = client.Execute(request);
var content = response.Content; // raw content as string
// or automatically deserialize result
// return content type is sniffed but can be explicitly set via RestClient.AddHandler();
RestResponse<Person> response2 = client.Execute<Person>(request);
var name = response2.Data.Name;
// easy async support
client.ExecuteAsync(request, response => {
Console.WriteLine(response.Content);
});
// async with deserialization
var asyncHandle = client.ExecuteAsync<Person>(request, response => {
Console.WriteLine(response.Data.Name);
});
// abort the request on demand
asyncHandle.Abort();

How to add access-control-allow-methods to method in C# POST

I am trying to sending a POST to a java web-service with my windows phone app using this c# code:
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
var requestContent = new StringContent(json);
requestContent.Headers.ContentType = new
MediaTypeWithQualityHeaderValue("application/json");
var response = await client.PostAsync(requestUri, requestContent);
//...
}
but I am getting a 400 Bad Request and sending this header:
POST [myreq] HTTP/1.1
Content-Type: application/json
Content-Length: 340
Accept-Encoding: identity
Accept: application/json
User-Agent: NativeHost
Host: [myhost]
Connection: Keep-Alive
Pragma: no-cache
and the only difference that I see from a valid similar (to the same web service) android java request is this line in my header:
access-control-allow-methods=[POST]
How to include this access-control-allow-methods with C#?
for future help
client.DefaultRequestHeaders.Add("Access-Control-Allow-Methods", "POST");

Categories