简体   繁体   English

将对象的复杂属性序列化为标量值

[英]Serialize complex property of object as scalar value

Suppose we have the following class definitions 假设我们有以下类定义

public class A
{
    public string Name { get; } = "Johny Bravo";
    public B ComplexProperty { get; } = new B();
}

public class B
{
    public string Prop1 { get; } = "value1";
    public string Prop2 { get; } = "value2";
    public int Prop3 { get; } = 100;

    public override string ToString()
    {
        return this.Prop3.ToString();
    }
}

when serialized 序列化时

var a = new A();
var str = JsonConvert.SerializeObject(a);

it will result in the following json string 这将导致以下json字符串

{
   "Name":"Johny Bravo",
   "ComplexProperty":{
      "Prop1":"value1",
      "Prop2":"value2",
      "Prop3":100
   }
}

How do we make the ComplexProperty serialize as scalar value? 我们如何使ComplexProperty序列化为标量值? The desired result must be this one: 期望的结果必须是这样的:

{
   "Name":"Johny Bravo",
   "ComplexProperty":100
}

Your code will not compile because you are assigning a B class to int value But I think I get what you want: 您的代码将无法编译,因为您正在将B类分配给int值,但是我想我得到了您想要的:

 class Program
    {


    static void Main(string[] args)
    {
        var a = new A();
        var str = JsonConvert.SerializeObject(a);
        Console.Write(str);
    }
}

public class A
{
    public string Name { get; } = "Johny Bravo";
    [JsonIgnore]
    public B ComplexProperty { get; } = new B();
    [JsonProperty("ComplexProperty")]
    public int complexValue => ComplexProperty.Prop3;
}

public class B
{
    public string Prop1 { get; } = "value1";
    public string Prop2 { get; } = "value2";
    public int Prop3 { get; } = 100;

    public override string ToString()
    {
        return this.Prop3.ToString();
    }
}

Since you want your object to be flat (only 1 level depth), you need to have the property on your A class. 由于您希望对象是平坦的(只有1级深度),因此需要在A类上具有该属性。 Since you don't want to have Your complex object in the json result, you have to ignore it, and since you need to have the same name on the Json results, you have to tell to json serializer to serialize your data with the required name 由于您不想在json结果中包含您的复杂对象,因此您必须忽略它,并且由于您需要在Json结果中使用相同的名称,因此您必须告诉json序列化器使用所需的序列化数据名称

The proper solution to this problem is to use a custom JsonConverter that can handle your type. 解决此问题的正确方法是使用可处理您的类型的自定义JsonConverter Especially in the case where you don't have control over the code of A and B classes. 尤其是在您无法控制A和B类的代码的情况下。 Here's the sample code 这是示例代码

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var a = new A();
            var str = JsonConvert.SerializeObject(a, new JsonSerializerSettings()
            {
                Converters = new List<JsonConverter>()
                {
                    new BTypeJsonConverter()
                }
            });
        }
    }

    public class A
    {
        public string Name { get; } = "Johny Bravo";
        public B ComplexProperty { get; } = new B();
    }

    public class B
    {
        public string Prop1 { get; } = "value1";
        public string Prop2 { get; } = "value2";
        public int Prop3 { get; } = 100;

        public override string ToString()
        {
            return this.Prop3.ToString();
        }
    }

    public class BTypeJsonConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var b = value as B;
            if (b == null) return;
            writer.WriteValue(b.ToString());
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
            JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(B);
        }
    }
}

Add another property and set the serializing PropertyName to first one. 添加另一个属性,并将序列化PropertyName设置为第一个。 If your class A comes from a 3rd party library, create a class that derives from A and add the new property. 如果您的A类来自第三方库,请创建一个从A派生的类并添加新属性。

public class A
{
    public string Name { get; } = "Johny Bravo";
--> [JsonIgnore]
    public B ComplexProperty { get; } = new B();
 -->[JsonProperty(PropertyName = "ComplexProperty")]
--> public string ComplexPropertyText { get{ return ComplexProperty.ToString(); } }
}

public class B
{
    public string Prop1 { get; } = "value1";
    public string Prop2 { get; } = "value2";
    public int Prop3 { get; } = 100;

    public override string ToString()
    {
        return this.Prop3.ToString();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM