This seems to be a bug in JSON.NET, and I think you should report it . It works fine in LINQPad for any property name other than $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; } }
Obviously, Json.NET uses $id as a reserved word to help 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"}]
However, it looks like this should allow you to grab the $id property if you are not using link processing.
As a workaround, you can parse it in a JObject and directly output the property:
var id = JObject.Parse(s)["$id"]; var obj = JsonConvert.DeserializeObject<DocData>(s); obj.id = id;
source share