Dan*_* L. 4 c# serialization json json.net
我MetadataType用来为以下类型定义Json.NET属性,然后在其ToString()方法中使用Json.NET对其进行序列化:
namespace ConsoleApp1
{
public interface ICell
{
int Id { get; }
}
public interface IEukaryote
{
System.Collections.Generic.IEnumerable<ICell> Cells { get; }
string GenericName { get; }
}
public sealed partial class PlantCell
: ICell
{
public int Id => 12324;
}
public sealed partial class Plant
: IEukaryote
{
private readonly System.Collections.Generic.IDictionary<string, object> _valuesDict;
public Plant()
{
_valuesDict = new System.Collections.Generic.Dictionary<string, object>();
var cells = new System.Collections.Generic.List<PlantCell>();
cells.Add(new PlantCell());
_valuesDict["Cells"] = cells;
_valuesDict["GenericName"] = "HousePlant";
}
public System.Collections.Generic.IEnumerable<ICell> Cells => _valuesDict["Cells"] as System.Collections.Generic.IEnumerable<ICell>;
public string GenericName => _valuesDict["GenericName"] as string;
public int SomethingIDoNotWantSerialized => 99999;
public override string ToString()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(this,
new Newtonsoft.Json.JsonSerializerSettings()
{
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
}
);
}
}
[System.ComponentModel.DataAnnotations.MetadataType(typeof(PlantMetadata))]
public sealed partial class Plant
{
[Newtonsoft.Json.JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)]
internal sealed class PlantMetadata
{
[Newtonsoft.Json.JsonProperty]
public System.Collections.Generic.IEnumerable<ICell> Cells;
[Newtonsoft.Json.JsonProperty]
public string GenericName;
//...
}
}
class Program
{
static void Main(string[] args)
{
var plant = new Plant();
System.Console.WriteLine(System.String.Format("Output is {0}", plant.ToString()));
System.Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是Plant.ToString()将返回'{}'.这是为什么?它以前工作过.我做的唯一改变是在PlantMetadata我改变MemberSerializationOptIn而不是OptOut的地方,因为我想要包含的属性少于遗漏.
正如Newtonsoft在本期中所述,MetadataTypeAttributeJson.NET实际上支持属性.但是,MetadataClassType当相应的"真实"成员是属性时,Json.NET似乎要求成员必须是属性,而当相应的"真实"成员是字段时,Json.NET要求成员必须是属性.因此,如果我Plant按如下方式定义您的类型,则需要序列化两个属性和一个字段:
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.
Run Code Online (Sandbox Code Playgroud)
然后,PlantMetadata还必须有两个属性和一个字段才能成功序列化:
//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;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我制作Cells或GenericName成为字段,或者FieldIWantSerialized是属性,那么他们就不会选择序列化.
样品工作 .Net小提琴.
请注意,此外,我发现MetadataClassType属性显然必须与真实属性具有相同的返回类型.如果我改变你的PlantMetadata如下:
[JsonObject(MemberSerialization.OptIn)]
internal sealed class PlantMetadata
{
[JsonProperty]
public object Cells { get; set; }
[JsonProperty]
public object GenericName { get; set; }
[JsonProperty]
public object FieldIWantSerialized;
}
Run Code Online (Sandbox Code Playgroud)
然后只FieldIWantSerialized序列化,而不是属性. .Net小提琴#2显示了这种行为.这可能是牛顿问题; 如Microsoft文档中定义元数据类中的属性:
这些属性的实际类型并不重要,编译器会忽略它们.接受的方法是将它们全部声明为Object类型.
如果重要,您可以向Newtonsoft 报告有关退货类型限制的问题 - 或者报告一个问题,要求MetadataTypeAttribute更全面地记录其支持的详细信息.
| 归档时间: |
|
| 查看次数: |
284 次 |
| 最近记录: |