0

I am aware that there is already a very similar question here, but unfortunately the top answer did not help me.

I want to POST some data to a RESTful web service via Unity Webrequest. As the documentation says,

The data in postData will be escaped, then interpreted into a byte stream via System.Text.Encoding.UTF8.

The data in postData is stored in JSON format. The remote web service will deserialize all incoming data using NewtonSoft.Json.

Unfortunately, the remote web service throws a JsonReaderException, with the message "Unexpected character encountered while parsing value: %. Path '', line 0, position 0." That is because the posted data look something like this as a string (truncated):

%7b%22LogType%22%3a%22Drill%22%2c%22Action%22%3a%22Started%22%2c%22Description%22%3a%22...

I tried to translate the incoming data from UTF-8 into ASCII before calling the Newtonsoft.Json library to deserialize it:

byte[] contentBytes = await Request.Content.ReadAsByteArrayAsync();
string postContents = Encoding.ASCII.GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII, contentBytes));

However, JsonReaderException is still thrown, because postContents still looks something like this:

%7b%22LogType%22%3a%22Drill%22%2c%22Action%22%3a%22Started%22%2c%22Description%22%3a%22...

What should I do to ensure that the remote web service can successfully deserialize the data it receives?

M.Y. Babt
  • 2,733
  • 7
  • 27
  • 49
  • 1
    I think your data became URL encode in transit. Forget about ASCII, that would be just one more problem. – H H Jun 17 '19 at 13:52
  • I would expect you could just cal `UrlDecode()` on it, but I'm at all confident in suggesting that's the best approach, in case there's a way to handle it earlier in the process... – Broots Waymb Jun 17 '19 at 13:52
  • 2
    `The data in postData will be escaped...` <-- that's the problem. Just send it as an object and let the web server deal with it itself. – Reinstate Monica Cellio Jun 17 '19 at 13:52
  • 1
    Post all the relevant C# code, client and server if possible. – H H Jun 17 '19 at 13:53
  • 3
    Unity is not being helpful here by posting the body as an `x-www-form-urlencoded` type, which the server apparently is unwilling to interpret. From what I gather from the docs, you can't use the static convenience method and you'll need to construct an explicit `UnityWebRequest` instance and set the `uploadHandler` to a `RawUploadHandler` instance (assuming you can't modify the server code to handle a form instead). – Jeroen Mostert Jun 17 '19 at 13:56
  • 2
    @JeroenMostert When it comes to web requests, Unity is still in 2001 it seemed – Camilo Terevinto Jun 17 '19 at 13:58
  • There are many duplicates if you just search for "unity3d post JSON" : https://stackoverflow.com/questions/38109658/unity-post-request-using-www-class-using-json | https://stackoverflow.com/questions/45470315/unity-3d-call-post-api-with-json-request – Camilo Terevinto Jun 17 '19 at 14:08

2 Answers2

1

The data you're receiving is URL encoded.

For example:

  • %7b is {
  • %22 is "
  • %3a is :

So the start of the received URL encoded string is this:

{"LogType":"Drill"

which is clearly a valid JSON string.

So, what you need to do is to url decode it to a regular JSON string, and then use JSON.NET to deserialize it.

JotaBe
  • 38,030
  • 8
  • 98
  • 117
  • Problem is that the OP is _sending_ this, the other side has to decode. – H H Jun 17 '19 at 14:08
  • @HenkHolterman That comment doesn't make too much sense. The OP's code both sends and receives, it can be handled at any end – Camilo Terevinto Jun 17 '19 at 14:23
  • Actually it's not clear who owns that "remote web service". THe question does focus on the client though. – H H Jun 17 '19 at 14:25
0

    //url decode to byte[]
    byte[] bytes = HttpUtility.UrlDecodeToBytes(urlstring);
    //byte[] to jsonstring
    string json = Encoding.UTF8.GetString(bytes);

classname decoded = JsonConvert.DeserializeObject<classname>(json);