0

I serialize a class in an azure function app and collect it via response to post in Unity3d. It's a WebGL project and it works fine on Editor but throws exception on browser (chrome/firefox):

using Newtonsoft.Json;
    namespace ARTFunctions
    {
    public class LoginResponse
        {
            public string status { get; set; }
            public string token { get; set; }
            public string clientDB { get; set; }
            public string clientTable { get; set; }
            [JsonConstructor]
            public LoginResponse() { }
        }
    public async Task<System.String> MyFunctionApp([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", "head", Route = null)] HttpRequest req, ILogger log)
            {
    LoginResponse logResp = new LoginResponse();
    logResp.status = "Success";
    logResp.clientDB = "userDB";
    logResp.clientTable = "thisTable";
    logResp.token="abc";
    return JsonConvert.SerializeObject(logResp);
    }

In Unity3d, I collect the serialized object but get constructor error:

using Newtonsoft.Json;
public class C_UnityClass: MonoBehaviour
{
    public void AtButtonPressed()
        {
          UnityWebRequest www = UnityWebRequest.Post("https://xxx.azurewebsites.net/api/MyFunctionApp", formData);
          yield return www.SendWebRequest();
          string queryResult = www.downloadHandler.text;
          var logResp = JsonConvert.DeserializeObject<LoginResponse>(queryResult);
          debug.log("logResp"+logResp.token);
        }
    }

And create non-Mono LoginResponse class with JsonContructor:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class LoginResponse
{
   public string status { get; set; }
   public string token { get; set; }
   public string clientDB { get; set; }
   public string clientTable { get; set; }
   [JsonConstructor]
   public LoginResponse (){}
   //I also tried adding [JsonConstructor] to this constructor but throws error too
   public LoginResponse(string status, string token, string clientDB, string clientTable)
 {
    this.status = status;
    this.token = token;
    this.clientDB = clientDB;
    this.clientTable = clientTable;
 }
}

Error: JsonSerializationException: Unable to find a constructor to use for type LoginResponse. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'status', line 1, position 10. at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract objectContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, Newtonsoft.Json.Serialization.JsonProperty containerProperty, System.String id, System.Boolean& createdFromNonDefaultCreator) [0x00000] in <00000000000000000000000000000000>:0

EDIT: If I use a single empty constructor for LoginResponse labelled at [JsonConstructor] I get exception as if constructor fails at azure function app. Worth noting this all works when run from Unity editor, fails on browser (tested for chrome/firefox):

"Unexpected end of Stream, the content may have already been read by another component. ","token":null,"clientDB":null,"clientTable":null}"

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class LoginResponse
{
   public string status { get; set; }
   public string token { get; set; }
   public string clientDB { get; set; }
   public string clientTable { get; set; }
   [JsonConstructor]
   public LoginResponse (){}
}
Sergio Solorzano
  • 476
  • 9
  • 29
  • 1
    is it the version compatible with unity? what is your nugget package you are using? – Frenchy Apr 08 '20 at 09:49
  • Hey @Frenchy Nuget for Function app is Newtonsoft.Json 12.0.3, Unity 8.0.0 – Sergio Solorzano Apr 08 '20 at 12:03
  • 1
    you can't create `MonoBehaviour` instances using an constructor! If it should be an constructor btw there would be no `class` but only `public C_UnityClass () {}` but as said it is not allowed by Unity to have such a constructor in any `MonoBehaviour` class anyway ... do you need this to be of type `MonoBehaviour`? – derHugo Apr 08 '20 at 12:04
  • Hey @derHugo it'll be a jump the hoop exercise to set it up without Mono and I'll try. But does JsonSerialization in the code above need a constructor for C_UnityClass? The error message says yes and that's why I added it, but only LoginResponse class is serialized. – Sergio Solorzano Apr 08 '20 at 12:11
  • 1
    you didn't add any constructor at all ... what you have there is a nested class definition ... as said a constructor would have no `class` keyword but rather only `public C_UnityClass () {}`! – derHugo Apr 08 '20 at 12:13
  • thanks @derHugo , I had made a mess. I've updated the post to the correct code (no mono serializable class). Error remains with this update though :( – Sergio Solorzano Apr 08 '20 at 13:15
  • 1
    Try to add a default constructor `public LoginResponse() { }` .. also convert all the properties to fields by removing `{get; set;}`. Also make sure you are using a Json .Net which is compatible with Unity like e.g. [this wrapper](https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347) .. in later Unity versions it is in the PackageManager afaik – derHugo Apr 08 '20 at 13:25
  • @Frenchy I am using Json.Net for Unity in asset store and it's the most up to date. How can I update the Newtonsoft package for Unity as this nuget suggests? (https://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@2.0/changelog/CHANGELOG.html?_ga=2.99714398.1701259840.1585295260-11394776.1585295260) No option for nuget in Visual studio Unity's project. Package Manager doesn't show Newtonsoft. – Sergio Solorzano Apr 08 '20 at 13:25
  • Yep @derHugo I'm using Json.Net wrapper (I'm on 2019.3 Json not available on package manager) and with a single constructor and converting properties to fields I get a different error suggesting the constructor fails (I've edited the post with this) "Unexpected end of Stream, the content may have already been read by another component. ","token":null,"clientDB":null,"clientTable":null}" – Sergio Solorzano Apr 08 '20 at 14:17
  • thank you @derHugo I've had to stop working on this as a more critical issue has appeared when running the unity webgl build from browser (editor and postman works fine). I need to revisit this post once i resolve https://stackoverflow.com/questions/61113793/unity-webgl-does-not-post-to-azure-function-app-form-already-read#61113793 – Sergio Solorzano Apr 09 '20 at 12:12

1 Answers1

2

Please reduce your strip engine code level to low.

screenshoot

It works

sujoybyte
  • 584
  • 4
  • 19
yangganboy
  • 21
  • 3