简化JSON序列化对象

时间:2019-06-03 07:41:59

标签: c# serialization json.net

鉴于以下2个课程(为简便起见而编辑),我正在生成问题列表。每个问题都分配有一个“ UserAccount”。

然后我想序列化问题列表,但是对于每个UserAccount,我只想编写'Id'属性(不包括UserAccount对象上的任何其他属性)。

我认为我需要一个自定义转换器来执行此操作,但是不确定如何拦截任何出现的UserAccount属性,而仅序列化其ID属性。

public class Question
{
    public int Id { get; set; }
    public string Ask { get; set; }
    public UserAccount CreatedBy { get; set; }
}

public class UserAccount
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

这是理想的结果JSON的样子:

[
   {
      "Id":1,
      "Ask":"Question 1",
      "CreatedBy":{
         "Id":1
      }
   },
   {
      "Id":2,
      "Ask":"Question 2",
      "CreatedBy":{
         "Id":1
      }
   },
   {
      "Id":3,
      "Ask":"Question 3",
      "CreatedBy":{
         "Id":1
      }
   }
]

我不想针对UserAccount类使用“忽略”属性,因为在其他一些商业案例中,我可能希望所有属性都进行序列化。实际上,我不想修改Question或UserAccount类。

3 个答案:

答案 0 :(得分:1)

您要有条件地忽略其他属性。为此,使用NewtonJson,您可以在类旁边的具有以下标志的属性中添加一个方法( bool ShouldSerialize [PropertyName] ),有关更多详细信息,请参见official documentation

因此您的代码将如下所示

public class UserAccount
{
    // This will be serialized
    public int Id { get; set; }

    // This may (or may not) be be serialized depending on your condition
    public string Name { get; set; }
    // This also may (or may not) be be serialized depending on your condition
    public string Email { get; set; }

    public bool ShouldSerializeName()
    {
        if(someCondition)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public bool ShouldSerializeEmail()
    {
        if(someCondition)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

如果您不想编辑原始类,则可以将它们包装在另一个类中(或从它们继承),然后使用派生的类。因此,您只需继承属性并将方法添加到派生类。这可能是一种可能的解决方案(我不确定您是否可以获得更好的解决方案)。

答案 1 :(得分:0)

如果要使用NewtonSoft,则必须在prop中添加“ JsonIgnore”属性(或在类中添加“ DataContract”,在prop中添加“ DataMember”)或实现IContractResolver

https://www.newtonsoft.com/json/help/html/ReducingSerializedJSONSize.htm

答案 2 :(得分:0)

您可以根据自己的需求创建一个custom JsonConverter,并且可以在'WriteJson'方法中尝试以下实现:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    JToken t = JToken.FromObject(value);

    if (t.Type != JTokenType.Object)
    {
        t.WriteTo(writer);
    }
    else
    {
        JObject o = (JObject)t;
        var property = o.Properties().FirstOrDefault(p => p.Name == "CreatedBy");
        if(property != null)
        {
            o.Remove(property.Name);
            var newObj = new JObject();
            newObj.Add(new JProperty("Id",((JObject)property.Value).Properties().First(p => p.Name == "Id").Value));
            var newProperty = new JProperty(property.Name, newObj);
            o.Add(newProperty);
            o.WriteTo(writer);
        }
    }
}

序列化代码如下:

var json = JsonConvert.SerializeObject(questions,  // your list of 'Question'
                                       Newtonsoft.Json.Formatting.Indented, 
                                       new MyCustomJsonConverter(typeof(Question)));