0

I'm trying to deserialize a JSON string but it keeps returning an object with default values (false, null, etc).

The JSON I'm working with is coming from a web service and is quite long. I've pasted it here: https://pastebin.com/6LrfSVJE

The structure is of the following:

"Data": [SITE, SITE, SITE, etc.]
"Success": BOOLEAN,
"Message": STRING,

Where a Site looks like this:

"__type" : STRING
"ID": INTEGER,
"UniqueIdentifier": GUID/STRING,
"Network": INTEGER,
"LandOwner": INTEGER (nullable),
"PermitHolder": INTEGER (nullable),
"Name": STRING,
"Alias": STRING (unique),
"Notes": STRING,
"Latitude": DOUBLE (nullable),
"Longitude": DOUBLE (nullable),
"Elevation": DOUBLE (nullable),
"TimeZoneName": STRING,
"TimeZoneAbbreviation": STRING,
"TimeZoneOffset": INTEGER,
"CreationDate": STRING ISO-8601,
"ModificationDate": STRING ISO-8601,
"GPSLandmark": STRING

I've replicated these in C# to use with Json.NET:

public class SiteList
{
    public bool Success { get; set; }
    public string Message { get; set; }
    public IList<Site> Data { get; set; }
}

public class Site
{
    public string __type { get; set; }
    public int ID { get; set; }
    public string UniqueIdentifier { get; set; }
    public int Network { get; set; }
    public int LandOwner { get; set; }
    public int PermitHolder { get; set; }
    public string Name { get; set; }
    public string Alias { get; set; }
    public string Notes { get; set; }
    public double Latitude { get; set; }
    public double Longitude { get; set; }
    public double Elevation { get; set; }
    public string TimeZoneName { get; set; }
    public string TimeZoneAbbreviation { get; set; }
    public int TimeZoneOffset { get; set; }
    public string CreationDate { get; set; }
    public string ModificationDate { get; set; }
    public string GPSLandmark { get; set; }
}

And I'm deserializing it as such:

string message = /* I make my service call here - same string as the JSON pasted above */
var sitelist = JsonConvert.DeserializeObject<Infrastructure.SiteList>(message);

If my data structures were incorrect, I'd expect the Json.NET function to return null. But it actually does return a SiteList, just with values of data=null, message=null, success=false.

This code was working a few days ago, but recently the web service was changed and the site data structure now contains the __type field. And ever since then the deserialization is failing.

I've tried not including the __type field at all, naming it "type", "Type", "__type", "__Type", but I always get the same result. I'm not exactly sure how Json.NET matches variable names but the introduction of the __type field does seem to have caused the issue, and it doesn't help that the name doesn't follow the previous convention.

Does anyone have a solution or see any mistake I may have overlooked?

dbc
  • 104,963
  • 20
  • 228
  • 340
zwaller
  • 87
  • 11
  • I can parse the message using Json.NET's Linq capabilities. For instance the following would work just fine: `JObject sitelist = JObject.Parse(message); JToken data = sitelist["Data"];` And I would be able to pull out specific data from the sites with `data[index]["Alias"];`, `data[index]["ID"];`, etc. So I'm assuming the string isn't malformed in any way. – zwaller Dec 08 '17 at 05:54
  • can you share the value of the message variable ? so that we can check – Guruparan Giritharan Dec 08 '17 at 05:58
  • The message value is an empty string, it never has any contents when the service call was successful. – zwaller Dec 08 '17 at 06:04
  • 1
    I don't see any problems with your classes. I can deserialize into them just fine with the JSON you have posted. See [fiddle](https://dotnetfiddle.net/2meS0K). – Brian Rogers Dec 08 '17 at 06:08
  • That's really weird. Well at least I know now my classes aren't incorrect. I'm gonna try updating my Newtonsoft package, other than that I'm kind of at a loss. – zwaller Dec 08 '17 at 06:17
  • I meant that the Message field inside the SiteList was an empty string, that's where an error message would go if the call wasn't successful. The message string inside my code where I make the service call contains the entire Json string. I misinterpreted the first comment's question – zwaller Dec 08 '17 at 06:28
  • The problem is with your service call, if your service is returning an empty string check that first, then you can check the deserializing part – Guruparan Giritharan Dec 08 '17 at 07:29
  • @zwaller - rather than adding an answer inside your question, you could [answer your own question](https://stackoverflow.com/help/self-answer) so future readers can easily know the problem is resolved. – dbc Dec 08 '17 at 18:01

1 Answers1

2

FIX:

I never mentioned that my SiteList and Site inherited from an abstract base class - the fact that it was inherited never messed up the functionality before. However I recently added the [DataContract] attribute to this base class so that I can use some of its inherited classes in my own web service, and it turns out that was what was breaking the deserialization. Removing the attribute or not inheriting from a DataContract class fixes the issue.

zwaller
  • 87
  • 11
  • 1
    The reason why `[DataContract]` applied to the base class affects how Json.NET serializes the derived class is explained [here](https://stackoverflow.com/a/29203876/3744182). – dbc Dec 08 '17 at 20:57