Convert Array of Objects to json string

I want to upload asked questions statistics to web server and this is the structure for it.

For this, I have decide to use JsonUtility.ToJson to convert object data into json from.

Number of questions are dynamic within each round so I have decided to use dynamic way of generation json string so directly I can submit it to web server.

Something like this kind of coding, I have done:

IEnumerator SendQuestionsStatEnumerator()
    {

        List<Question> gameAppearedQuestionList = FilterGameAppearedQuestionList();
        QuestionStats[] questionStatsArr = new QuestionStats[gameAppearedQuestionList.Count];

        for (int i = 0; i < gameAppearedQuestionList.Count; i++)
        {
            QuestionStats questionStats = new QuestionStats();
            questionStats.iQuestionId = gameAppearedQuestionList[i].QuestionNo;
            questionStats.nDuration = gameAppearedQuestionList[i].QuestionDuration;
            questionStats.nQir = gameAppearedQuestionList[i].QuestionIndexRating;
            questionStats.nQuestionResult = gameAppearedQuestionList[i].QuestionResult;
            questionStats.nOffense = gameAppearedQuestionList[i].QuestionOffense;
            questionStats.nDefense = gameAppearedQuestionList[i].QuestionDefense;

            questionStatsArr[i] = questionStats;
        }


        Debug.Log("appeared questions: " + JsonUtility.ToJson(questionStatsArr[0]));

        WWWForm form = new WWWForm();
        form.AddField(ARG_USER_ID, AdhocStorage.userProfile.userId.ToString());
        form.AddField(ARG_QUESTONS_STAT, JsonHelper.ToJson(questionStatsArr));

        using (UnityWebRequest webRequest = UnityWebRequest.Post(GameConstants.HOOPSENGLISH_BASE_URL + GameConstants.WEB_GAME_QUESTION_STATS, form))
        {
            webRequest.SetRequestHeader(HEADER_AUTHORIZATION, AdhocStorage.userProfile.accessToken);

            // Request and wait for the desired page.
            yield return webRequest.SendWebRequest();

            switch (webRequest.result)
            {
                case UnityWebRequest.Result.ConnectionError:
                case UnityWebRequest.Result.DataProcessingError:
                    Debug.LogError("Error: " + webRequest.error);
                    break;
                case UnityWebRequest.Result.ProtocolError:
                    Debug.LogError("HTTP Error: " + webRequest.error);
                    break;
                case UnityWebRequest.Result.Success:
                    Debug.Log("Received: " + webRequest.downloadHandler.text);
                    break;
            }
        }
    }

But JsonUtility.ToJson statement can able to generate json string for me only for one object but I want to convert my array of objects converted into json string and this is not working, its giving me empty curly brackets in response.

Because of this my server sending code was working.

Please suggest me, how convert my array of objects data to json string?

The built in JSON-lite Unity has is pretty bad, and can’t serialise naked arrays. Easiest solution would be to wrap your questionStatsArr in another object, perhaps a plain class, and serialise it like that.

The alternative is to use a more robust serialiser, but then you run into the issue of not being able to serialise any UnityEngine.Objects.

1 Like

Thank for your suggestion, I implemented as per you mentioned and I got json string as per I want but still there is no response from the web server.
Here is my code:

[Serializable]
    class QuestionStats
    {
        public int iQuestionId = 0;
        public int nDuration = 0;
        public int nQir = 0;
        public int nQuestionResult = 0;
        public int nOffense = 0;
        public int nDefense = 0;
    }

    [Serializable]
    class QuestionStatsGroup
    {
        public QuestionStats[] aStat;

        public QuestionStatsGroup(int size)
        {
            aStat = new QuestionStats[size];
        }
    }

    IEnumerator SendQuestionsStatEnumerator()
    {

        List<Question> gameAppearedQuestionList = FilterGameAppearedQuestionList();
        QuestionStatsGroup questionStatsGroup = new QuestionStatsGroup(gameAppearedQuestionList.Count);

        for (int i = 0; i < gameAppearedQuestionList.Count; i++)
        {
            QuestionStats questionStats = new QuestionStats();
            questionStats.iQuestionId = gameAppearedQuestionList[i].QuestionNo;
            questionStats.nDuration = gameAppearedQuestionList[i].QuestionDuration;
            questionStats.nQir = gameAppearedQuestionList[i].QuestionIndexRating;
            questionStats.nQuestionResult = gameAppearedQuestionList[i].QuestionResult;
            questionStats.nOffense = gameAppearedQuestionList[i].QuestionOffense;
            questionStats.nDefense = gameAppearedQuestionList[i].QuestionDefense;

            questionStatsGroup.aStat[i] = questionStats;
        }

        JSONObject questionsStatJsonObj = new JSONObject(JsonUtility.ToJson(questionStatsGroup));
        JSONObject aStatObj = questionsStatJsonObj[ARG_QUESTONS_STAT];
        Debug.Log("after converting to json: " + aStatObj.Print());

        WWWForm form = new WWWForm();
        form.AddField(ARG_USER_ID, AdhocStorage.userProfile.userId.ToString());
        form.AddField(ARG_QUESTONS_STAT, aStatObj.Print());

        using (UnityWebRequest webRequest = UnityWebRequest.Post(GameConstants.HOOPSENGLISH_BASE_URL + GameConstants.WEB_GAME_QUESTION_STATS, form))
        {
            webRequest.SetRequestHeader(HEADER_AUTHORIZATION, AdhocStorage.userProfile.accessToken);

            // Request and wait for the desired page.
            yield return webRequest.SendWebRequest();

            switch (webRequest.result)
            {
                case UnityWebRequest.Result.ConnectionError:
                case UnityWebRequest.Result.DataProcessingError:
                    Debug.LogError("Error: " + webRequest.error);
                    break;
                case UnityWebRequest.Result.ProtocolError:
                    Debug.LogError("HTTP Error: " + webRequest.error);
                    break;
                case UnityWebRequest.Result.Success:
                    Debug.Log("Received: " + webRequest.downloadHandler.text);
                    break;
            }
        }
    }

Now within this code, the code can’t able to cross, yield return webRequest.SendWebRequest(); statement.

8399469--1108917--debug console.png

As you are seeing, json string is in the form as per I want.
But when I execute the code, it is not crossing yield statement and I can’t able to find a bug.
Please guide me into this.

Do not use the static “UnityWebRequest.Post” method. It creates a webrequest that tries to encode the supplied string as an “x-www-form-urlencoded”. You can not send raw text with this method. In the latest versions of Unity they have deprecated the method as far as I know and replaced it with two other versions. There are plenty of threads about this issue. The static Post method is kinde unintuitive. It is briefly mentioned in the documentation.

1 Like

Then what is the best suitable way to call web service?
Because my project is completely dependent on different web services.

I research on Google and I found Unity Documentation and examples mentioned usage of UnityWebRequest.Post method.

As I said there are countless of threads, not only here on the forum but even stackoverflow. In essence you have to set an UploadHandlerRaw manually in order to post raw data and set the content type to “application/json”. Another common alternative is to use the static “Put” method and before actually sending the request you manually overwrite the method with “POST”.

Overall I have little progress within my code, I have just added application/json as header of the web request and it started executing the web service.
Here is the updated code:

After adding this line, I have started getting 500 Internal Server Error, something like this:

Please guide me into this because I am at the edge to complete this. I have tried to execute web service multiple times but its giving me the same error always.

@siddharth3322 Consider comparing your curl request to the request coming from Unity using Charles Proxy https://support.unity.com/hc/en-us/articles/115002917683-Using-Charles-Proxy-with-Unity