Newtonsoft.Json deserialize object in Xamarin iOS

2019-01-15 21:57发布

问题:

I'm getting some very weird behaviour in my Xamarin.Forms Project.

I'm retrieving some serialized data from a REST API. I'm then trying to use Json.NET to deserialize that to an object.

This works perfectly fine on Android and if I copy the code to a .NET console application it also works. However in my iOS project, the call to .DeserializeObject() just returns null. It doesn't throw an error or complain in any way.

I did find this discussion: https://forums.xamarin.com/discussion/15152/deserialization-not-working-with-json-net-on-ios-device-ios-simulator-works, but I didn't link all assemblies in the first place and trying to set the attribute suggested by T.J.Purtell.1752 didn't help either.

Could anyone tell me what to do here?

Thanks a lot!

Jan

EDIT

Here's a sample response of what I'm trying to deserialize:

[
   {
      "Isbn":{
         "Isbn10":"0099910101",
         "Isbn13":"9780099910107"
      },
      "Title":"A Farewell to Arms",
      "Authors":[
         "Ernest Hemingway"
      ],
      "Publisher":"Random House",
      "ReleaseDate":"1994",
      "PageCount":293,
      "Description":"In 1918 Ernest Hemingway went to war, to the 'war to end all wars'. He volunteered for ambulance service in Italy, was wounded and twice decorated. Out of his experiences came A Farewell to Arms. Hemingway's description of war is unforgettable. He recreates the fear, the comradeship, the courage of his young American volunteer and the men and women he meets in Italy with total conviction. But A Farewell to Arms is not only a novel of war. In it Hemingway has also created a love story of immense drama and uncompromising passion.",
      "ThumbnailUrl":"http://books.google.com/books/content?id=m68LhBiNv8YC&printsec=frontcover&img=1&zoom=1&source=gbs_api"
   },
   {
      "Isbn":{
         "Isbn10":"9044538780",
         "Isbn13":"9789044538786"
      },
      "Title":"Het huis van de namen",
      "Authors":[
         "Colm Tóibín"
      ],
      "Publisher":"Singel Uitgeverijen",
      "ReleaseDate":"2017-08-24",
      "PageCount":0,
      "Description":"Klytaimnestra heeft veel moeten doorstaan. Haar man heeft haar kind, haar mooie oudste dochter, geofferd aan de goden, en zij heeft hem niet kunnen tegenhouden. Hoe kan ze dit ooit te boven komen? En hoe zullen haar andere twee kinderen reageren op deze ontwrichtende gebeurtenis? Eén ding neemt ze zich voor: haar man zal dit met de dood moeten bekopen.",
      "ThumbnailUrl":"http://books.google.com/books/content?id=yl8yDwAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
   }
]

回答1:

Just got back to this problem. In case anyone‘s wondering: Turns out the Xamarin Live Player I’ve recently had to use has some problems with Json.NET. (https://developer.xamarin.com/guides/cross-platform/live/limitations/)

I knew it had to be something stupid... Well maybe I can save someone else some time!



回答2:

Thanks a lot to all the responses so far! Sadly none of them worked for me.

After a lot of trial and error I found that I am able to access my data like so:

var blub = JsonConvert.DeserializeObject(booksString);
foreach (var element in (JArray)blub)
{
    var blublub = ((JObject)element).SelectToken("$.Title").ToString();
}

But it would be an absolute pain if I had to implement my whole API this way... Are there any other ideas from you guys?



回答3:

Setting iOS Build Linker Behavior to "Link Framework SDKs only" fixed this for me.

As T.J.Purtell.1752 describes in the referenced xamarin thread, the Xamarin Linker will strip out unused types, methods, and fields.

Link Framework SDKs only prevents that happening for my application classes, which is fine in my conmtext.



回答4:

Please try like this:

Item item = JObject.Parse (json).ToObject<Item> ();

Yes, it's kind of ugly fix, but if it's working, it's working :)



回答5:

Based on the JSON being returned it would need to be desrialized to an array where the objects map for example

public class Isbn {
    public string Isbn10 { get; set; }
    public string Isbn13 { get; set; }
}

public class Item {
    public Isbn Isbn { get; set; }
    public string Title { get; set; }
    public IList<string> Authors { get; set; }
    public string Publisher { get; set; }
    public string ReleaseDate { get; set; }
    public int PageCount { get; set; }
    public string Description { get; set; }
    public string ThumbnailUrl { get; set; }
}

And then deserialized like

var items = JsonConvert.DeserializeObject<Item[]>(json);