As stated by Newtonsoft in this issue, MetadataTypeAttribute
attributes are in fact supported by Json.NET. However, it appears that Json.NET requires that the MetadataClassType
members must be properties when the corresponding "real" members are properties, and fields when the corresponding "real" members are fields. Thus, if I define your Plant
type as follows, with two properties and one field to be serialized:
public sealed partial class Plant : IEukaryote
{
public System.Collections.Generic.IEnumerable<ICell> Cells { get { return (_valuesDict["Cells"] as System.Collections.IEnumerable).Cast<ICell>(); } }
public string GenericName { get { return _valuesDict["GenericName"] as string; } }
public string FieldIWantSerialized;
public int SomethingIDoNotWantSerialized { get { return 99999; } }
// Remainder as before.
Then the PlantMetadata
must also have two properties and one field for them to be serialized successfully:
//Metadata.cs
[System.ComponentModel.DataAnnotations.MetadataType(typeof(PlantMetadata))]
public sealed partial class Plant
{
[JsonObject(MemberSerialization.OptIn)]
internal sealed class PlantMetadata
{
[JsonProperty]
public IEnumerable<ICell> Cells { get; set; }
[JsonProperty]
public string GenericName { get; set; }
[JsonProperty]
public string FieldIWantSerialized;
}
}
If I make Cells
or GenericName
be fields, or FieldIWantSerialized
be a property, then they do not get opted into serialization.
Sample working .Net Fiddle.
Note that, in addition, I have found that the MetadataClassType
properties apparently must have the same return type as the real properties. If I change your PlantMetadata
as follows:
[JsonObject(MemberSerialization.OptIn)]
internal sealed class PlantMetadata
{
[JsonProperty]
public object Cells { get; set; }
[JsonProperty]
public object GenericName { get; set; }
[JsonProperty]
public object FieldIWantSerialized;
}
Then only FieldIWantSerialized
is serialized, not the properties. .Net Fiddle #2 showing this behavior. This may be a Newtonsoft issue; as stated in the Microsoft documentation Defining Attributes in Metadata Classes:
The actual type of these properties is not important, and is ignored
by the compiler. The accepted approach is to declare them all as of
type Object.
If it matters, you could report an issue about the return type restriction to Newtonsoft - or report an issue asking that details of their support for MetadataTypeAttribute
be more fully documented.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…