Overwrite Json property name in c#

前端 未结 2 835
野的像风
野的像风 2020-12-01 21:52

I have a class with following fields. Those properties are used to serialize as json object when it needs to call a external rest API method.

public class C         


        
2条回答
  •  误落风尘
    2020-12-01 22:33

    You'll have to override DefaultContractResolver and implement your own mechanism to provide the PropertyName (in JSON). I will provide a full example code to show deserialization and serialization with a runtime generated PropertyName. Currently, it modifies the Test field to Test5 (in all models). You should implement your own mechanism (using an attribute, a reserved name, a table or whatever.

    class Program
    {
        static void Main(string[] args)
        {
            var customer = new Customer() {Email = "asd@asd.com", Test = "asdasd"};
            var a = Serialize(customer, false);
            var b = Serialize(customer, true);
            Console.WriteLine(a);
            Console.WriteLine(b);
    
            var desA = Deserialize(a, false);
            var desB = Deserialize(b, true);
    
            Console.WriteLine("TestA: {0}", desA.Test);
            Console.WriteLine("TestB: {0}", desB.Test);
    
        }
    
        static string Serialize(object obj, bool newNames)
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.Formatting = Formatting.Indented;
            if (newNames)
            {
                settings.ContractResolver = new CustomNamesContractResolver();
            }
    
            return JsonConvert.SerializeObject(obj, settings);
        }
        static T Deserialize(string text, bool newNames)
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.Formatting = Formatting.Indented;
            if (newNames)
            {
                settings.ContractResolver = new CustomNamesContractResolver();
            }
    
            return JsonConvert.DeserializeObject(text, settings);
        }
    }
    class CustomNamesContractResolver : DefaultContractResolver
    {
        protected override IList CreateProperties(System.Type type, MemberSerialization memberSerialization)
        {
            // Let the base class create all the JsonProperties 
            // using the short names
            IList list = base.CreateProperties(type, memberSerialization);
    
            // Now inspect each property and replace the 
            // short name with the real property name
            foreach (JsonProperty prop in list)
            {
                if (prop.UnderlyingName == "Test") //change this to your implementation!
                    prop.PropertyName = "Test" + 5;
    
            }
    
            return list;
        }
    }
    
    public class Customer
    {
        [JsonProperty(PropertyName = "email")]
        public string Email { get; set; }
    
        public string Test { get; set; }
    
    }
    

    Output:

    {
      "email": "asd@asd.com",
      "Test": "asdasd"
    }
    {
      "email": "asd@asd.com",
      "Test5": "asdasd"
    }
    TestA: asdasd
    TestB: asdasd
    

    As you see, when we use Serialize(..., false) - the field's name is Test and when we use Serialize(..., true) - the field's name is Test5, as expected. This also works for deserialization.

    I have used this answer as insperation for my answer: https://stackoverflow.com/a/20639697/773879

提交回复
热议问题