Deserializing a byte[] from C# Tool in Node.js - c#

I have inherited a C# tool that sends a serialized byte array of meeting data to an online calendar application. The online calendar uses a node.js API. My problem is that the serialized byte array is not getting parsed correclty by node.js (IE, in express the req.body object is empty). I am look for either a way to send the data so it can be parsed by Node.js, or a parser in Node.js that can handle c# byte arrays. It is JSON formatted. Here is the code that sends the request:
string json = JsonConvert.SerializeObject(reallyPost, Formatting.None);
byte[] postThisz = Encoding.ASCII.GetBytes(json);
byte[] response = wc.UploadData(siteUrl, postThisz);
At the moment I'm simply trying to log the data. The route is caught here:
app.post('/remotePost', api.remotePost);
which uses this controller:
module.exports.remotePost = function (req, res) {
console.log(req);
console.log(req.body);
sendJsonResponse(res, 200, "remote posted.");
};
The req.body gets populated by my parsing middleware:
app.use(bodyParser.json());
However this cannot handle the byte array sent by the C# program. I can solve this either by finding a parser that will handle the C# POST correctly (byte[] type), or finding a C# module that can make a post containing something of the format that JSON.stringify() returns.

It's advisable to change the encoding to utf8
Encoding.UTF8.GetBytes(json);
Then, you should also set the appropriate headers before upload
wc.Headers.Add("Content-Type", "application/json; charset=utf8");

Related

Can I allow raw unicode in HTTP headers using NSUrlSession?

I'm constructing an NSUrlSession as follows:
NSUrlSessionConfiguration sessionCfg = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration("mySpecialSessionName");
NSUrlSessionDelegate sessionDelegate = new MySessionDelegate();
urlSession = NSUrlSession.FromConfiguration(sessionCfg, sessionDelegate, NSOperationQueue.MainQueue);
And invoking background downloads with custom HTTP headers:
NSMutableUrlRequest mutableRequest = new NSMutableUrlRequest();
mutableRequest.HttpMethod = "POST";
mutableRequest.Url = NSUrl.FromString(someEndpoint);
mutableRequest["MyCustomHeader"] = someStringWithUnicodeChars;
mutableRequest.Body = NSData.FromString(somePostBody);
NSUrlSessionDownloadTask downloadTask = m_UrlSession.CreateDownloadTask(mutableRequest);
downloadTask.Resume();
However, the header value string seems to get truncated at the first character above 255. For example, the header value:
SupeЯ Σario Bros
is received by the server as
Supe
When instead using .NET HttpClient on xamarin, unicode header strings successfully make it to the server unmodified. However, I'd like to make use of NSUrlSession's background downloading feature.
(I realize that support of unicode in HTTP headers is hit-and-miss, but since the HTTP server in this case is a particular custom server that doesn't currently support things like base64 encoding, passing the raw string is desired)
I don't know whether you'll be able to make that work, but two things come to mind:
What you have here is equivalent to calling setValue:forKey: on the URL request. I don't think that will do what you're expecting. Try calling the setValue:forHTTPHeaderField: method instead.
Try specifying the encoding before you specify your custom header value, e.g. [theRequest setValue:#"...; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
If neither of those helps, you'll probably have to encode the data in some way. I would suggest using URL encoding, because that's a lot simpler to implement on the server side than Base64. For the iOS side, see this link for info on how to URL-encode a string:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/WorkingwithURLEncoding/WorkingwithURLEncoding.html

How to upload TextFile from Windows forms to a specific Url with WebClient?

I want to send a normal text file from my VisualStudio C# Windows Forms Application via "Post" to an Url with a WebClient.
my code:
using(WebClient w = new WebClient())
{
w.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
string HtmlResult = w.UploadString(#"http://xxx/api/test", "Post", #"C:\Temp\T.txt");
}
This is what I found so far. When I run this code the post method in my web project gets hit but the param is null (which is understandable since its data type is a string but it is also null when I change the file address to a simple string like "test").
So my real problem is that I can´t send my text data to my URL.
First, your ContentType should be "application/text" not "application/x-www-form-urlencoded".
Second, this method defaults to POST for HTTP/HTTPS so use the overload that takes two string parameters UploadString("destination Url", "data"). If you just must use the three parameter overload, the method should be "POST" not "Post".
This method does not read the file for you, you will need to add code to read the contents of your file into a string, then pass that string to the data parameter of the UploadString method.
I probably should add that, in the recieving api you will read the data from the Request.InputStream object. As with any stream you will read it into a byte array and need to encode it back to a string. You must use the same encoding that was used to read the file into a string.
The stream InputStream is a one-way readonly stream, so you will need to read it in it's entirety into a byte array before encoding back to a string.

How to get server response in JSON?

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.

C# transfer image via json. Error

I have c# client and c# server (mvc4 api controller) and I want to transfer image via json.
I write on the client:
var memoryStream = new MemoryStream();
image.Save(memoryStream, ImageFormat.Jpeg);
var baseStr64 = Convert.ToBase64String(memoryStream.ToArray());
response.Image = baseStr64;
(new JavaScriptSerializer).Serialize(response);
...Sending
Without image controller gets the request class normal, but with image base64 string field I have a null parameter in controller. Then I noticed that output json fails in online json validators on this base64 field.
My output json can be found here: http://pastebin.com/wnAJpZGV
How to transmit image correctly?
It is possible that the Json string is too big. The PasteBin example you showed was over 200K in length. Check this StackOverflow article on how you might be able to fix the problem:
Can I set an unlimited length for maxJsonLength in web.config?

Using WebClient to pass arrays as part of message body for post action

I am writing a console application that needs to perform a POST to an MVC controller. I am using the WebClient class to perform the POST. But I'm having trouble understanding how to add arrays to the message body.
For simple parameters, it seems to work if I do this:
using (var client = new WebClient())
{
var values = new NameValueCollection
{
{ "userName", "userName" },
{ "password", "passwordGoesHere"}
};
byte[] responseArray = client.UploadValues(String.Format("{0}/Mobile/StartSession", serverAddress), values);
Debug.WriteLine(String.Format("\r\nResponse received was :\n{0}\n", Encoding.ASCII.GetString(responseArray)));
}
I was trying to find how to pass arrays in the message body when using WebClient (for calling one of the other methods). I came across this solution: POST'ing arrays in WebClient (C#/.net)
It appears the solution actually passes parameters in the query string (and not in the message body). This seems to work in any case, as the HttpPost method on the MVC controller is still receiving the correct information. However, another method requires that I pass an image as an array of bytes. This is too large to be passed in the querystring and so the call fails.
So my question is, using the code I provided above, how can I add arrays in there as well. So an array of bytes for example, but also an array of strings.
If any one can provide me with a solution it would be much appreciated, or if I'm incorrect in my thinking please let me know.
Thanks
Instead of using array of bytes maybe you should POST a file in the same way files are uploaded from browser from file inputs. This way you will save some transfered bytes, but you have to use HttpWebRequest instead of WebClient. More about this solution is here:
Upload files with HTTPWebrequest (multipart/form-data)
You upload bytes as "multipart/form-data" content type. On the server you will receive the streams of bytes in Request.Files collection.

Categories