6

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

user3063281
  • 299
  • 1
  • 3
  • 6
  • possible duplicate of [Dynamic Object with Dollar on String](http://stackoverflow.com/questions/20318261/dynamic-object-with-dollar-on-string) – L.B Dec 03 '13 at 21:20

1 Answers1

1

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;
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • Ha, just my luck. I guess (hope) having a $ as a leading character is a very rare occurrence. Maybe I can also get the service developer to change that, or explain why they want it like that. Thanks – user3063281 Dec 03 '13 at 22:34
  • @user3063281: It turns out, it's even more specific than that. JSON.NET apparently uses `$id` as a reserved name to help it deal with object references. See http://stackoverflow.com/questions/11542144/how-to-remove-id-during-json-serialization – StriplingWarrior Dec 03 '13 at 22:37