Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

deserialize json in C# with illegal variable characters

Tags:

json

c#

.net

I'm writing a .NET library (using Newtonsoft) that interacts with a REST service, and I have a service that's returning json, but the json id field is called '$id'. So I can't just create a corresponding $id property in my C# data class. I tried to use something like

    [JsonObject(MemberSerialization.OptOut)]
    public class DocData
    {
        [JsonProperty("$id")]
        public string id { get; set; }

        public string Name { get; set; }
    }

but while Name gets assigned, the id property does not. Anyone know how to map this json key to .NET?

Thanks

like image 252
user3063281 Avatar asked Dec 03 '13 21:12

user3063281


Video Answer


1 Answers

It looks like this is a bug in JSON.NET, and I think you should report it. It works fine in LINQPad for any property name except $id.

void Main()
{
    var s = JsonConvert.SerializeObject(new DocData{id = "hi", Name = "world"}).Dump();
    JsonConvert.DeserializeObject<DocData>(s).Dump();
}

public class DocData
{
    // [JsonProperty("i$d")] // this would work 
    // [JsonProperty("_id")] // as would this
    // [JsonProperty("$name")] // and even this
    [JsonProperty("$id")] // but this fails
    public string id { get; set; }

    public string Name { get; set; }
}

Evidently Json.NET uses $id as a reserved word to help it deal with object references.

    var dd = new DocData{id = "hi", Name = "world"};
    JsonConvert.SerializeObject(new[]{dd, dd}, new JsonSerializerSettings{PreserveReferencesHandling = PreserveReferencesHandling.Objects}).Dump();
// Output: [{"$id":"1","$id":"hi","Name":"world"},{"$ref":"1"}]

Still, it seems like it should let you capture the $id property if you're not using reference handling.

As a workaround, you can parse it into a JObject, and pull the property out directly:

    var id = JObject.Parse(s)["$id"];
    var obj = JsonConvert.DeserializeObject<DocData>(s);
    obj.id = id;
like image 63
StriplingWarrior Avatar answered Oct 15 '22 20:10

StriplingWarrior