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;