Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Bug Sometimes UnityWebRequest corrupts JSON

Discussion in 'Web' started by Suvitruf, Nov 28, 2023.

  1. Suvitruf

    Suvitruf

    Joined:
    Sep 3, 2014
    Posts:
    39
    It works in Editor and Android, but in WebGL build sometimes the body is corrupted.

    Code (CSharp):
    1.             using (UnityWebRequest request = new UnityWebRequest(requestData.Url, requestData.GetMethod()))
    2.             {
    3.                 request.timeout = Constants.REQUEST_TIME_OUT;
    4.                 request.downloadHandler = new DownloadHandlerBuffer();
    5.                 request.disposeDownloadHandlerOnDispose = true;
    6.                 request.disposeUploadHandlerOnDispose = true;
    7.                 request.SetRequestHeader("Content-Type", "application/json");
    8.  
    9.                 if (requestData.Headers != null)
    10.                 {
    11.                     foreach (var header in requestData.Headers)
    12.                         request.SetRequestHeader(header.Key, header.Value);
    13.                 }
    14.                
    15.                 if (!string.IsNullOrEmpty(requestData.Token))
    16.                     request.SetRequestHeader("Authorization", "Bearer " + requestData.Token);
    17.  
    18.                 if (requestData.Body != null)
    19.                 {
    20.                     string stringBody = JsonConvert.SerializeObject(requestData.Body);
    21.                     Debug.Log("stringBody: " + stringBody);
    22.                     var body = Encoding.UTF8.GetBytes(stringBody);
    23.                    
    24.                     using (var uh = new UploadHandlerRaw(body))
    25.                     {
    26.                         request.uploadHandler?.Dispose();
    27.                         request.uploadHandler = uh;
    28.                     }
    29.                 }
    30.                
    31.                 yield return request.SendWebRequest();
    The same request could be ok, but next time sent with corrupted data.

    upload_2023-11-28_19-56-50.png

    I print stringBody, and it always fine.
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,438
    How big is your payload?

    And are you 100% sure that you are not looking at a string with a different encoding, say UTF-16?

    Also I'm wondering why you convert the json string to a byte[]. I'm thinking if the DownloadHandler has a text property, the UploadHandler would have one too.
     
  3. Suvitruf

    Suvitruf

    Joined:
    Sep 3, 2014
    Posts:
    39
    Doesn't matter. It can be 100 bytes, can be 10kb.

    Interesting question. How can I check it?

    It's the common way to send it: https://forum.unity.com/threads/unitywebrequest-post-url-jsondata-sending-broken-json.414708/
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,438
    That link is over 7 years old. Whatever they talk about, it may no longer be valid.

    Not sure about the encoding but I can imagine you need to set the header of the request to indicate that it is binary and not a string. Since you convert the string to byte[] it will LOOK as if it's a string to the endpoint but in fact it's just the byte representation of the string which may contain escape codes for instance those \u0. But if the endpoint thinks its an ASCII string then that endpoint will work incorrectly with the string.

    Meaning: the "corruption" is not a corruption, it's a mismatch of the string encoding when sent vs when received. And I tend to think you set that in the header that the encoding is UTF8.
     
  5. Suvitruf

    Suvitruf

    Joined:
    Sep 3, 2014
    Posts:
    39
    It may sound crazy, but I replaced using:

    Code (CSharp):
    1.                     using (var uh = new UploadHandlerRaw(body))
    2.                     {
    3.                         request.uploadHandler?.Dispose();
    4.                         request.uploadHandler = uh;
    5.                     }
    with direct UploadHandlerRaw creation

    Code (CSharp):
    1.                     uh = new UploadHandlerRaw(body);
    2.                     request.uploadHandler?.Dispose();
    3.                     request.uploadHandler = uh;
    With manual uh?.Dispose(); in the end.

    And now everything is fine...