C# Json.Net序列化(JsonConverter.WriteJson)

C# Json.Net序列化(JsonConverter.WriteJson),c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我正在使用奇妙的Newtonsoft json.Net(版本4.5.7.15008)库进行序列化和反序列化 我想: 序列化时忽略.Databag属性 自定义编写的JSON。首先获取默认JSON,对其进行更改,并将更改后的JSON写入结果 这些是我的课程: public interface ISimpleDatabag { string Databag { get; set; } } [JsonConverter(typeof(JsonDataBagCreationConverter&l

我正在使用奇妙的Newtonsoft json.Net(版本4.5.7.15008)库进行序列化和反序列化

我想:

  • 序列化时忽略
    .Databag
    属性
  • 自定义编写的JSON。首先获取默认JSON,对其进行更改,并将更改后的JSON写入结果
  • 这些是我的课程:

    public interface ISimpleDatabag
    {
        string Databag { get; set; }
    }
    
    [JsonConverter(typeof(JsonDataBagCreationConverter<Department>))]
    public class Department : ISimpleDatabag
    {
        [JsonIgnoreAttribute]
        public string Databag { get; set; }
    
        public string Name { get; set; }
        public Telephone[] Phones { get; set; }
    }
    
    [JsonConverter(typeof(JsonDataBagCreationConverter<Telephone>))]
    public class Telephone : ISimpleDatabag
    {
        [JsonIgnoreAttribute]
        public string Databag { get; set; }
    
        public string Name { get; set; }
        public string AreaCode { get; set; }
        public string Number { get; set; }
    }
    
    public class JsonDataBagCreationConverter<T> : JsonConverter where T : ISimpleDatabag, new()
    {
        // Json.Net version 4.5.7.15008
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // problem 1
            string jsonAsDefault = ""; // The json that would have been written have I not overridden WriteJson. How?
            // problem 1.a: Ignore the Databag property when writing the json.
            string myChangedJson = jsonAsDefault + "WhatEverIWant";
            // problem 2
            // Write myChangedJson to the resulting json string instead of jsonAsDefault
    
    
            // try
            //serializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize; // Otherwise self referencing loop detected, but then...
            // JObject jobj = JObject.FromObject(value, serializer); //... Stack overflow
            // jobj.WriteTo(writer);
    
            // try
            // writer.WriteValue(value); // "Unsupported type: Department
    
            // try
            //serializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize; // Otherwise self referencing loop detected, but then...
            // serializer.Serialize(writer, value); // ...Stack overflow
    
            // try
            // base.WriteJson(writer, value, serializer); base class is abstract
        }
    
        protected T Create(Type objectType, JObject jsonObject)
        {
            return new T();
        }
    
        public override bool CanConvert(Type objectType)
        {
            return typeof(T).IsAssignableFrom(objectType);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jsonObject = JObject.Load(reader);
            var target = Create(objectType, jsonObject);
            serializer.Populate(jsonObject.CreateReader(), target); // Will call this function recursively for any objects that have JsonDataBagCreationConverter as attribute
            ((ISimpleDatabag)target).Databag = jsonObject.ToString(); // This is where custom data is stored in databag
            return target;
        }
    }
    
    public class IgnoreDataBagContractResolver : DefaultContractResolver
    {
        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            JsonProperty property = base.CreateProperty(member, memberSerialization);
            if (property.PropertyName.ToLower() == "databag")
            {
                property.Ignored = true;
                return property;
            }
            return property;
        }
    }
    
    公共接口ISimpleDatabag
    {
    字符串数据包{get;set;}
    }
    [JsonConverter(类型(JsonDataBagCreationConverter))]
    公共类部门:ISimpleDatabag
    {
    [JsonIgnoreAttribute]
    公共字符串数据库{get;set;}
    公共字符串名称{get;set;}
    公用电话[]电话{get;set;}
    }
    [JsonConverter(类型(JsonDataBagCreationConverter))]
    公共类电话:ISimpleDatabag
    {
    [JsonIgnoreAttribute]
    公共字符串数据库{get;set;}
    公共字符串名称{get;set;}
    公共字符串区域代码{get;set;}
    公共字符串编号{get;set;}
    }
    公共类JsonDataBagCreationConverter:JsonConverter,其中T:ISimpleDatabag,new()
    {
    //Json.Net版本4.5.7.15008
    公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
    {
    //问题1
    string jsonAsDefault=“;//如果我没有重写WriteJson,本应编写的json。如何编写?
    //问题1.a:在编写json时忽略DataAG属性。
    字符串myChangedJson=jsonAsDefault+“WhatEverIWant”;
    //问题2
    //将myChangedJson写入结果json字符串,而不是jsonAsDefault
    //试一试
    //serializer.ReferenceLoopHandling=ReferenceLoopHandling.Serialize;//否则检测到自引用循环,但。。。
    //JObject jobj=JObject.FromObject(值,序列化程序);/…堆栈溢出
    //jobj.WriteTo(作家);
    //试一试
    //writer.WriteValue(值);/“不支持的类型:部门
    //试一试
    //serializer.ReferenceLoopHandling=ReferenceLoopHandling.Serialize;//否则检测到自引用循环,但。。。
    //serializer.Serialize(writer,value);/…堆栈溢出
    //试一试
    //WriteJson(writer、value、serializer);基类是抽象的
    }
    受保护的T创建(类型objectType,JObject jsonObject)
    {
    返回新的T();
    }
    公共覆盖布尔CanConvert(类型objectType)
    {
    返回typeof(T).IsAssignableFrom(objectType);
    }
    公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
    {
    var jsonObject=JObject.Load(读卡器);
    var target=Create(objectType,jsonObject);
    serializer.Populate(jsonObject.CreateReader(),target);//将递归调用此函数,用于将JsonDataBagCreationConverter作为属性的任何对象
    ((ISimpleDatabag)target.Databag=jsonObject.ToString();//这是自定义数据存储在Databag中的位置
    回报目标;
    }
    }
    公共类IgnoreDataBagContractResolver:DefaultContractResolver
    {
    受保护的重写JsonProperty CreateProperty(MemberInfo成员、MemberSerialization MemberSerialization)
    {
    JsonProperty属性=base.CreateProperty(成员,成员序列化);
    if(property.PropertyName.ToLower()==“数据包”)
    {
    property.Ignored=true;
    归还财产;
    }
    归还财产;
    }
    }
    
    以及调用:

    public Form1()
        {
            InitializeComponent();
    
            string jsonInput = "{\"Name\": \"Seek4\" , \"CustomDepartmentData\": \"This is custom department data\", \"Phones\":[ {\"Name\": \"A\", \"AreaCode\":444, \"Number\":11111111} ,{\"Name\": \"B\", \"AreaCode\":555, \"Number\":987987987}, {\"Name\": \"C\", \"AreaCode\":222, \"Number\":123123123, \"CustomPhoneData\": \"This is custom phone data\"} ] }";
            Department objDepartment = JsonConvert.DeserializeObject<Department>(jsonInput); // Yes, it works well
            objDepartment.Name = "Seek4Cars";
            string json = ToSeek4Json(objDepartment); // This is my problem: Ignore Databag property and control the output json for each property
        }
    
        public static string ToSeek4Json(object objectToConvertToJson)
        {
            JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
            IgnoreDataBagContractResolver contractResolver = new IgnoreDataBagContractResolver();
            serializerSettings.ContractResolver = contractResolver;
            return JsonConvert.SerializeObject(objectToConvertToJson, Formatting.None, serializerSettings);
        }
    
    public Form1()
    {
    初始化组件();
    字符串jsonInput=“{\'Name\”:\“Seek4\”,\“CustomDepartmentData\”:\“这是自定义部门数据\”,\“Phones\”:[{\'Name\”:“A\”,“AreaCode\”:444,\“Number\”:11111111},{\'Name\:“B\”,“AreaCode\”:555,\“Number\”:987987987},{\'Name\:“C\”,“AreaCode\”,“AreaCode\”:222,\'Number\:123123,\“Customphone\”这是自定义电话数据:}";
    Department objDepartment=JsonConvert.DeserializeObject(jsonInput);//是的,它工作得很好
    objDepartment.Name=“Seek4Cars”;
    string json=ToSeek4Json(objDepartment);//这是我的问题:忽略Databag属性并控制每个属性的输出json
    }
    公共静态字符串ToSeek4Json(对象objectToConvertToJson)
    {
    JsonSerializerSettings serializerSettings=新的JsonSerializerSettings();
    IgnoreDataBagContractResolver contractResolver=新IgnoreDataBagContractResolver();
    serializerSettings.ContractResolver=ContractResolver;
    返回JsonConvert.SerializeObject(objectToConvertToJson,Formatting.None,serializerSettings);
    }
    
    以下是我最后所做工作的简要说明