1

Currently I am just returning the json string to corresponding file from where Test1() is called and Deserializing there as ResponseClass r = JsonConvert.DeserializeObject(response_json) Send part I forget to make a class [Serializable].Its working fine now.

Part1:

public class Movie
{
    public string Name { get; set; }
    public string Description { get; set; }
    public string Classification { get; set; }
    public string Studio { get; set; }
    public DateTime? ReleaseDate { get; set; }
    public List<string> Genres{ get; set; }
}


public class ResponseClass
{
    public string SuccessStatus{ get; set; }
    public string next_link { get; set; }
}


private void Test1<T,Q>()
{
    string json = @"{
      'Name': 'Bad Boys',
      'ReleaseDate': '1995-4-7T00:00:00',
      'Genres': [
        'Action',
        'Comedy'
      ]
    }";


   //Here making network call with above json and getting correct response_josn
    Q response_obj = JsonConvert.DeserializeObject<Q>(reponse_json);
    print(response_obj);
}

I am calling Test1() as follows on button click:

Test1<Movie, ResponseClass>();

For the above example I am getting print log as ClassName+Movie (T FullName). I want to deserialize the string into that class. How to achieve that?

enter image description here

Part2 : If I have class as:

[Serializable]
public class Movie
{
    public string Name;
    public string Description;
    public string Classification;
    public string Studio;
    public DateTime ReleaseDate;
    public SubClass subClass;
    public List<SubClass> lsubclass;
}
[Serializable] //This was the mistake. 
public class SubClass
{
    public string a;
    public string b;
    public List<string> ReleaseCountries;
}

private Movie createValidMovieJson()
{
    Movie m = new Movie();

    SubClass sc = new SubClass();
    sc.a = "aaa";
    sc.b = "bbb";
    sc.ReleaseCountries = new List<string>();
    sc.ReleaseCountries.Add("Japan");
    sc.ReleaseCountries.Add("India");
    List<SubClass> lsC = new List<SubClass>();
    lsC.Add(sc);
    lsC.Add(sc);

    m.Name = "Bad Boys";
    m.Studio = "Pixa";
    m.subClass = sc;
    m.lsubclass = lsC;
    Debug.Log(JsonUtility.ToJson(m));  // value n log = {"Name":"Bad Boys","Description":"","Classification":"","Studio":"Pixa"}
    return m;
}

JsonUtility is returning empty value in place of subclass after using ToJson() as shown in above function.

Community
  • 1
  • 1
djkpA
  • 1,224
  • 2
  • 27
  • 57
  • How are you calling Test1? – David L Jan 22 '17 at 16:47
  • Edited question @David L – djkpA Jan 22 '17 at 16:48
  • You should be using [JsonUtility](http://stackoverflow.com/questions/36239705/deserialization-of-json-using-minijson-in-unity-c-sharp/36244111#36244111) in Unity. Let me know of that solves your problem. – Programmer Jan 22 '17 at 17:14
  • I just replaced `T m = JsonConvert.DeserializeObject(json);` with `T m = JsonUtility.FromJson(json);` it gives an error ArgumentException: JSON parse error: Missing a name for object member. – djkpA Jan 22 '17 at 17:41
  • @djkp Don't ignore answers. If it worked, you say it worked or it didn't then explain what's going on. – Programmer Jan 22 '17 at 19:37
  • why do you want to deserialize your json to Movie class. The only one common field of json and Movie i see is Name. All other are complete different – Maksim Simkin Jan 24 '17 at 07:57
  • @Programmer I edited the question , I tried what u said it worked. Thanks. But I am facing problem while having other class as a variable in Movie class. I explained and added codes in Question. – djkpA Jan 24 '17 at 08:05
  • It worked and I added mistake in
    in question
    – djkpA Jan 24 '17 at 10:19
  • I am sorry. What's the problem? – Programmer Jan 26 '17 at 03:15

2 Answers2

1

Based on the screenshot you added I think you are expecting to be able to treat the deserialized type as a Movie. This is the way to achieve that:

var movie = JsonConvert.DeserializeObject<Movie>(json);

Currently your deserialized object is being treated as type T - which could be anything since you have no generic type constraints on your method.

Andy Gibson
  • 187
  • 2
  • 7
  • My question is how to get that working for a generic method as shown above – djkpA Jan 22 '17 at 17:57
  • Ok in that case your generic method should have a return type of T and should return the deserialized object. Then you can call the method like: var movie = Test1(); – Andy Gibson Jan 22 '17 at 17:59
0

Like I said in the comment section, JsonUtility should do it.

I just replaced T m = JsonConvert.DeserializeObject(json); with T m = JsonUtility.FromJson(json); it gives an error ArgumentException: JSON parse error: Missing a name for object member.

Your json is invalid for JsonUtility. I believe you are using ' instead of ". This is why you are getting this error.

Use the function below to generate a valid json:

void createValidMovieJson()
{
    Movie m = new Movie();
    m.Name = "Bad Boys";
    m.ReleaseCountries = new List<string>();
    m.ReleaseCountries.Add("Japan");

    m.Studio = "Pixa";
    Debug.Log(JsonUtility.ToJson(m));
}

You will get:

 {"Name":"Bad Boys","Description":"","Classification":"","Studio":"Pixa","ReleaseCountries":["Japan"]}

When ecaped for testing, you will get:

{\"Name\":\"Bad Boys\",\"Description\":\"\",\"Classification\":\"\",\"Studio\":\"Pixa\",\"ReleaseCountries\":[\"Japan\"]}

For JsonUtility to work, you must add [Serializable] to the class and remove { get; set; } from them class variables.

If your goal is to convert any json to any data type then you have to return generic type then use Convert.ChangeType to convert it to that type.

It should look something like this:

// Use this for initialization
void Start()
{
    string json = "{\"Name\":\"Bad Boys\",\"Description\":\"\",\"Classification\":\"\",\"Studio\":\"Pixa\",\"ReleaseCountries\":[\"Japan\"]}";

    Movie movie = Load<Movie>(json);
    print(movie.Name);
}

[Serializable]
public class Movie
{
    public string Name;
    public string Description;
    public string Classification;
    public string Studio;
    public DateTime? ReleaseDate;
    public List<string> ReleaseCountries;
}

private T Load<T>(string json)
{
    object resultValue = JsonUtility.FromJson<T>(json);
    return (T)Convert.ChangeType(resultValue, typeof(T));
}
Community
  • 1
  • 1
Programmer
  • 121,791
  • 22
  • 236
  • 328
  • The OP ***specifically*** asked for a generic solution. That said, this question is still too unclear to answer properly. – David L Jan 22 '17 at 18:29
  • [@DavidL](http://stackoverflow.com/users/1165998/david-l) This is tagged as a Unity question. Make sure to read the tag before answering or downvoting answer next time. 1.You can't use JSON.Net in Unity. due to .NET version difference in Unity. 2.There is a pad version of JSON.Net for Unity but this problem can be solved without buying anything. 3.JsonUtility should be used since it is built into Unity and faster than JSON.Net in most cases. 3.As for generics, the `Test1()` function takes generics.Also, `T m = JsonUtility.FromJson(json);`. I think that's what OP meant. Happy coding! – Programmer Jan 22 '17 at 18:42
  • Thank you for the background on JSON.net in Unity. It is very useful. I've removed my comment related to it. But I disagree with how you consider this to be taking advantage of generics when you've buried a cast in a generic method. – David L Jan 22 '17 at 18:57
  • The `Movie movie = (Movie)(object)m;` cast you see is just for testing purposes. To show the Name from the class. That's not part of the answer. It's just to show OP that JsonUtility is able to deserialize the class. The **main** problem in the question is that OP cannot deserialize json to class. My solution is just telling OP to use JsonUtility and it explains many reasons why he is getting error while deserializing. – Programmer Jan 22 '17 at 19:06
  • That is fine, But this restricts me to use only movie class in Test1 to type cast , what if I have multiple classes and I want to type cast each class generically? That's one of the point of my question. Otherwise Andy Gibson solutions in his comments works fine for me. – djkpA Jan 23 '17 at 18:04