Jump to content
  • Advertisement
NDraskovic

UnityWebRequest result can't be deserialized to JSON

Recommended Posts

Hey guys,

I have a really weird problem. I'm trying to get some data from a REST service. I'm using the following code:
 

private void GetTheScores()
    {
        UnityWebRequest GetCommand = UnityWebRequest.Get(url);
        UnityWebRequestAsyncOperation operation = GetCommand.SendWebRequest();

        if (!operation.webRequest.isNetworkError)
        {
            ResultsContainer rez = JsonUtility.FromJson<ResultsContainer>(operation.webRequest.downloadHandler.text);
            Debug.Log("Text: " + operation.webRequest.downloadHandler.text);
        }
    }

The problem is that when I'm in Unity's editor, the request doesn't return anything (operation.webRequest.downloadHandler.text is empty, the Debug.Log command just prints "Text: "), but when I enter the debug mode and insert a breakpoint on that line, then it returns the text properly. Does anyone have an idea why is this happening?

The real problem I'm trying to solve is that when I receive the text, I can't get the data from the JSON. The markup is really simple:

[{"id":1,"name":"Player1"},{"id":2,"name":"Player2"}]

and I have an object that should accept that data:

[System.Serializable]
public class ResultScript {

    public int id;
    public string name;    
}

There is also a class that should accept the array of these objects (which the JSON is returning):

[System.Serializable]
public class ResultsContainer {

    public ResultScript[] results;

}

But when I run the code (in the debug mode, to get any result) I get an error: ArgumentException: JSON must represent an object type. I've googled it but none of the proposed solutions work for me.

Also (regardless if I'm in the debug mode or not) when I try to do some string operations like removing or adding characters to the GET result, the functions return an empty string as a result

Can you help me with any of these problems?

Thank you

Edited by NDraskovic
Added more information

Share this post


Link to post
Share on other sites
Advertisement

while my experience with json is limited the provided json does not seem to be correct, rather incomplete.

Either I would have done 

 

rez.results=JsonUtility.FromJson<ResultsContainer>(myJsonString);

or modified json as 

{"results":[{"id":1,"name":"Player1"},{"id":2,"name":"Player2"}]}

I am not sure if something else is the issue as I said I have limited experience here.

Edited by ankurra

Share this post


Link to post
Share on other sites

Did you try with the modified json? For modified json you can keep the original rez=JsonUtility.fromJson

I find Json To POJO Class converter really helpful. I know this isn't java, but the code helps. It is possible that the serialization from the object is not being done properly.

Share this post


Link to post
Share on other sites

Yeah I changed it so that it looks like an object, but didn't help.

I pulled just one entry from the array and hardcoded it into the function, and then it converts the object properly, so in worst case scenario, I'll parse the string myself and convert them one by one. 

The other part of the question is still puzzling me.

Share this post


Link to post
Share on other sites

I am not clear, single hardcoded entry  works for you. If you take single entry 

{"id":2,"name":"Player2"}

and it converts correctly, then please check the type you are converting as this is of type ResultScript and should not be able to convert ResultContainer.

It makes sense if you are doing conversion for ResultScript type one by one.

Also a small correction.

rez.results=JsonUtility.FromJson<ResultsScript>(myJsonString);

 

The unity forum however say that the json array deserialisation is not supported directly and you have to use a wrapper class

Please check that when you are using the modified json I mentioned in my previous reply you are using the following. 

rez=JsonUtility.FromJson<ResultsContainer>(myJsonString);

 

Edited by ankurra

Share this post


Link to post
Share on other sites

When you deserialize JSON in unity, the JSON must be one object (in your example you start with a list), also, if you ResultsContainer contains an array with ResultScript named "results", the returned JSON must contain a list with the same variable name, like this:

 

{
    "results": [{
            "id": 1,
            "name": "Player1"
        },
        {
            "id": 2,
            "name": "Player2"
        }
    ]
}

If you change your web service to return that JSON, maybe it will work.

Edited by flodihn

Share this post


Link to post
Share on other sites

I can't change the data on the server side, so I've added the "{\"results\": to the text I get (and of course the following closing bracket). Now I don't get any errors, but the results array is null.

Share this post


Link to post
Share on other sites

If your top level data is an array, then your serializable object must also be an array.

An object with an array member is different from just an array. Thus, you want to de-serialize into an array. It sounds like Unity's JSON doesn't support that (although that's legal JSON -- arrays and objects are allowed at top level) and you can't change the server, so you're in a tough spot.

If your data comes back as "empty" then chances are that you're being hit by some kind of web security restriction. In general, scripts that run from domain X, will not have access to data loaded from domain Y, unless the headers on the response from domain Y specifically white-list domain X. This is to avoid credentials theft and cross-site scripting of various kinds. The concept is called "cross-origin resource sharing" and you can find a link about it here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Perhaps the Unity editor implements those restrictions, and the service you're talking to does not include the appropriate headers.

Try looking at the data in Wireshark to see what you actually get on the wire. Also, try looking in the Unity web request documentation for properties that may affect CORS.

Share this post


Link to post
Share on other sites

Yeah, the data is just an array. I made my own simple parser, fortunatelly the data is not too complicated, so I'm just going trough the string and pulling out entries one by one and then using JSON to convert them to the objects I need, so let's say that this part is solved (it's not pretty, but it works). 

I managed to bypass the WebRequest problem by using WWW class instead of WebRequest, and that class works perfectly.

Thanks to everyone for your help.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!