在JSON C#

时间:2018-02-14 09:04:35

标签: c# json reflection json.net

我有一个特定的情况,我需要在序列化类时将类名作为属性包含在JSON中。棘手的部分是我需要动态地做这件事。我不能在调用序列化之前创建一个匿名类。

我用自定义属性修饰了我的类,如下所示:

 [OntologyArea("con", " http://someurl/area/DomicileAddress")]
    public class DomicileAddress : IContactPoint
    {

        [JsonProperty(PropertyName = "con:hasAddressPoint")]
        public IAddressPoint AddressPoint
        {
            get; set;
        }
    }

在上面的示例中,应该读取OntologyArea属性并将其作为属性包含在内。属性名称应该是OntologyArea +类名的第一个参数(即con:DomicileAddress),值应该是IAddressPoint的具体类。

棘手的部分是IAddressPoint的具体类可能需要执行与此处所示相同的操作:

[OntologyArea("geo", "http://someurl.net/geolocation")]
    public class StreetAddress : IAddressPoint
    {
        [JsonProperty("geo:hasStartingStreetNumber")]
        public string StartingStreetNumber
        {
            get; set;
        }
    }

JSON的一个例子:

"con:DomicileAddress" : {
    "con:hasAddressPoint" : {
        "geo:StreetAddress" : {
            "geo:hasEndingStreetNumber" : ""
        }
    }
}

因此,如果任何对象确实具有OntologyArea属性,我需要添加父级别。如果它不包含此属性,则应继续进行正常的血清化。

请告诉我如果我需要解释更多。

2 个答案:

答案 0 :(得分:0)

指定具体类型的解决方案是必须的还是仅仅是您提出的解决方案?

因为Json.NET内置了对接口类型或基类属性的实际类型进行编码的支持:

var json = JsonConvert.SerializeObject(myContract, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });

如果你真的需要一个完全自定义的逻辑,你必须实现一个转换器,它也可以传递给JsonSerializerSettings。它必须来自JsonConverter,您必须实现WriteJson方法以使用低级令牌发出所需的json sting,就像XmlWriter一样:

private class MyConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(IAddressPoint).IsAssignableFrom(objectType);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var address = (IAddressPoint)value;

        writer.WriteStartObject(); // {
        writer.WritePropertyName($"geo:{address.GetType().Name}"); // "geo:StreetAddress"
        // ... etc.
        writer.WriteEndObject(); // }

        // or you can just emit raw string:
        writer.WriteRaw(myJsonBody);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, 
    {
        // todo: and the deserialization part goes here
    }
}

答案 1 :(得分:0)

这指出了我正确的方向。我有一个在这个类中读取并附加到writer对象的属性。