How to get server response in JSON? - c#

I am uploading a .json file from my local drive:
using (WebClient client = new WebClient())
{
client.Headers.Add("Content-Type", "application/json");
byte[] resp = client.UploadFile("http://mycoolWebsite.com", "POST", "path to file");
string textResponse = System.Text.Encoding.ASCII.GetString(resp)
}
The response from client.UploadFile is of type byte[] when I want it to be json so I can more easily parse through it. How can I ask the server to give me back json?

The method is defined as returning byte[] with good reason. It allows the method to be used with any web service and return back the raw response from the server. Defining server-side response is the responsibility of the server (obviously). Your best bet is to take the raw response, encode it as text (as you're doing), and then check to see if the response contains well-formed JSON, allowing you to re-encode as JSON and parse at that time.
The response will be whatever the server returns; it's up to you to handle it.

Related

The request body did not contain the specified number of bytes

I am calling an API from by C# Windows service. In some cases the following error is being raised.
The request body did not contain the specified number of bytes. Got 101,379, expected 102,044
In the RAW Request captured using fiddler content length as specified.
Content-Length: 102044
In the response from the API I am receiving the following message.
The request body did not contain the specified number of bytes. Got 101,379, expected 102,044
The strange thing for me is that it does not happen for each and every request, it is generated randomly and different points. Code which I am using to get the content length is specified below.
var data = Encoding.ASCII.GetBytes(requestBody); // requestBody is the JSON String
webReqeust.ContentLength = data.Length;
Is it mandatory to provide content length in REST API calls ?
Edit 1:
This is what my sample code looks like for web request
webReqeust = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", requestURI, queryString));
webReqeust.Method = RequestMethod.ToString();
webReqeust.Headers.Add("Authorization", string.Format("{0} {1}", token_type, access_token));
webReqeust.Method = RequestMethod.ToString();
webReqeust.ContentType = "application/json";
var data = Encoding.ASCII.GetBytes(requestBody);
webReqeust.ContentLength = data.Length;
using (var streamWriter = new StreamWriter(webReqeust.GetRequestStream()))
{
streamWriter.Write(requestBody);
streamWriter.Flush();
streamWriter.Close();
}
I would suggest maybe instead try using HttpClient as done in the linked post from mjwills here. You don't have to use content length, but it sounds like that is being enforced by the API and ultimately you are trying to post too much.
Otherwise the way I see it is that something is making the request body too large. Is it serialized input data which gets encoded into a byte array? If that is what is happening then perhaps the correct length requirements are not being enforced on the data that composes the request body, and I would suggest inspecting what goes on in the composition of the request body object itself.

How do I pull data from a Slack API response with WebClient?

I am making a portal for our team's Slack channel, and I'm wanting to pull a list of all of our current users using the Slack Web API - using the method api/users.list.
The code I am playing around with is:
var response = client.UploadValues("https://slack.com/api/users.list",
"POST", new NameValueCollection()
{
{ "token" ,"mySecretToken"}
});
I get an OK response back, but I'm having trouble actually finding out how to pull the data I want. When I look at the response object all I have is an array of bytes.
What am I missing to actually pull back an object with the user list information?
I needed to encode the response.
Just add this after:
var encoding = new UTF8Encoding();
var responseText = encoding.GetString(response);
I can then use the responseText to pull out the data I need.

How to upload data with Microsoft.Net.Http?

In the past I made a class that shunk the request on an endpoint. Now, I create a dll that include this method, this is the code that I'm trying to convert on this library:
using (var client = new HttpClient())
{
string requestJson = JsonConvert.SerializeObject(data);
client.DefaultRequestHeaders.Add("token", token);
byte[] responseArray = client. 'there is no upload data method
// the bottom code is of the old method
byte[] responseArray = client.UploadData(requestURI, method, Encoding.UTF8.GetBytes(requestJson));
return Encoding.ASCII.GetString(responseArray);
}
In the not portable library System.Net I can call client.UploadData, but here I see only : postAsync and putAsync, there is a method that independent from the put or post request allow me to send the data from the client to the server? Thanks in advance.
In your old code you used some method passed in method parameter to send data with UploadData method, and it was probably POST or PUT. If you do not specify the method for UploadData, POST is being used. So you should use PostAsyncor PutAsync, based on you current code and the value of method parameter you pass to UploadData.
The simplest way would be to use something like this:
using(var client = new HttpClient())
{
var response = await client.PostAsJsonAsync(requestUrl, data);
return await response.Content.ReadAsStringAsync();
}
The code for PUT would be the same, but with PutAsJsonAsync
In an HTTP request PUT and POST are the correct ways to transmit data to a server, it does not make sense to send data independently of these methods. When you are using a client such as that available in System.Net this is merely being abstracted away from you.

Why does WebClient.UploadValues overwrites my html web page?

I'm familiar with Winform and WPF, but new to web developing. One day saw WebClient.UploadValues and decided to try it.
static void Main(string[] args)
{
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["thing1"] = "hello";
values["thing2"] = "world";
//A single file that contains plain html
var response = client.UploadValues("D:\\page.html", values);
var responseString = Encoding.Default.GetString(response);
Console.WriteLine(responseString);
}
Console.ReadLine();
}
After run, nothing printed, and the html file content becomes like this:
thing1=hello&thing2=world
Could anyone explain it, thanks!
The UploadValues method is intended to be used with the HTTP protocol. This means that you need to host your html on a web server and make the request like that:
var response = client.UploadValues("http://some_server/page.html", values);
In this case the method will send the values to the server by using application/x-www-form-urlencoded encoding and it will return the response from the HTTP request.
I have never used the UploadValues with a local file and the documentation doesn't seem to mention anything about it. They only mention HTTP or FTP protocols. So I suppose that this is some side effect when using it with a local file -> it simply overwrites the contents of this file with the payload that is being sent.
You are using WebClient not as it was intended.
The purpose of WebClient.UploadValues is to upload the specified name/value collection to the resource identified by the specified URI.
But it should not be some local file on your disk, but instead it should be some web-service listening for requests and issuing responces.

How to accept xml file in via http post method and parse request headers.?

I am sending Xml file from web broser rest client. I need to accept xml file in asp.net web api http post method.
How do I get xml file content , its file name and headers content from asp.net web api http post method.?
I referred a few msdn links such as http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2 , i did not get this tutorial
somehow i wrote code
HttpRequestMessage request = this.Request;
var task = this.Request.Content.ReadAsStreamAsync();
task.Wait();
Stream requestStream = task.Result;
string inp = request.Content.ReadAsStringAsync().Result;
string result = await request.Content.ReadAsStringAsync();
try
{
Stream fileStream = File.Create(#"c:\\test\\1.xml");
requestStream.CopyTo(fileStream);
fileStream.Close();
requestStream.Close();
}
catch (IOException)
{
throw new HttpResponseException("A generic error occured. Please try again later.", HttpStatusCode.InternalServerError);
}
through this above code i don't get full xml content.
I am completely new to asp.net web api and .net framework.
Please provide procedure to implement this and code.
If you are posting the XML file via File Upload, then this link at www.asp.net should help. Otherwise, if you are simply posting a string then you shouldn't need to do anything special other than supply a string parameter in your controller method to receive the XML string (in which case Web API will automagically do the mapping for you).

Categories