簡體   English   中英

將包含對象屬性的poco序列化為Json

[英]Serialize poco containing object property into Json

我有一類需要序列化才能傳遞給另一個系統。

該類包含一個定義為對象的屬性,因為該對象將包含的類的類型在運行時可能會有所不同。

我的課程看起來像是這種簡化的模型。

public class MyTestXML
{
    public string String1 { get; set; }
    public string String2 { get; set; }

    [System.Xml.Serialization.XmlElementAttribute("First", typeof(MyFirstObject),
                              Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
    [System.Xml.Serialization.XmlElementAttribute("Second", typeof(MySecondObject),
                              Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
    public object MyObject { get; set; }
}
public class MyFirstObject
{
    public string theFirstObjectString { get; set; }
}
public class MySecondObject
{
    public string theSecondObjectString { get; set; }
}

此類通過使用XmlElementAttribute和XmlSerializer完美地序列化為xml,但是當我嘗試將其序列化為Json(使用Newtonsoft Json.Net)時,該對象是未定義的類型,因此無法反序列化。

有沒有一種方法可以在序列化時在Json屬性中指定XmlElementAttribute以獲得相同的結果?

我想為序列化的對象提供Json的使用,因為它是xml大小的一半,但是除非我能解決對象屬性問題的序列化,否則我不能。

提前致謝。

您將必須創建自己的自定義序列化行為。 在這里看看這個答案: https : //stackoverflow.com/a/22722467/2039359關於如何為Json.Net實現自己的JsonConverter

在您的情況下,您可以執行以下操作來創建json

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            MyTestXML myTestXml = (MyTestXML) value;
            JObject jObject = JObject.FromObject(value);

            JProperty prop = jObject.Children<JProperty>().First(p=>p.Name.Contains("MyObject"));
            if (myTestXml.MyObject.GetType() == typeof (MyFirstObject))
            {
                prop.AddAfterSelf(new JProperty("First", JToken.FromObject(myTestXml.MyObject)));
                prop.Remove();
                jObject.WriteTo(writer);
            }
            else if (myTestXml.MyObject.GetType() == typeof (MySecondObject))
            {
                prop.AddAfterSelf(new JProperty("Second", JToken.FromObject(myTestXml.MyObject)));
                prop.Remove();
                jObject.WriteTo(writer);                    
            }
        }

反序列化時,類似這樣

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jo = JObject.Load(reader);

            MyTestXML myTestXml = new MyTestXML();

            serializer.Populate(jo.CreateReader(), myTestXml);

            object myObject = null;
            if (jo["First"] != null)
            {
                myObject = new MyFirstObject { TheFirstObjectString = jo["First"].SelectToken(@"TheFirstObjectString").Value<string>() };
            }

            if (jo["Second"] != null)
            {
                myObject = new MySecondObject { TheSecondObjectString = jo["Second"].SelectToken(@"TheSecondObjectString").Value<string>() };
            }

            myTestXml.MyObject = myObject;
            return myTestXml;
        }

要使用它,您將在序列化/反序列化時提供JsonConverter ,如下所示:

        var settings = new JsonSerializerSettings();
        settings.Converters.Add(new MyTextXmlJsonConverter());
        var a = JsonConvert.SerializeObject(myTestXml, settings);

希望這就是您要尋找的

另一種選擇是創建一個自定義合同解析器,它允許您檢測應用了哪個xml屬性。 然后,如果需要特定的輸出,則可以在屬性上應用自定義JsonConverter。

public class CustomContractResolver : DefaultContractResolver
{
    private readonly JsonMediaTypeFormatter formatter;

    public CustomContractResolver(JsonMediaTypeFormatter formatter)
    {
        this.formatter = formatter;
    }

    public JsonMediaTypeFormatter Formatter
    {
        [DebuggerStepThrough]
        get { return this.formatter; }
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        this.ConfigureProperty(member, property);
        return property;
    }

    private void ConfigureProperty(MemberInfo member, JsonProperty property)
    {
        if (Attribute.IsDefined(member, typeof(XmlElementAttribute), true))
        {
            var attribute = member.CustomAttributes.Where(x => x.AttributeType == typeof(XmlElementAttribute)).First();
            // do something with your attribute here like apply a converter
            property.Converter = new XmlAttributeJsonConverter();
        }            
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM