Overwrite Json property name in c#

前端 未结 2 821
野的像风
野的像风 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<Customer>(a, false);
            var desB = Deserialize<Customer>(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<T>(string text, bool newNames)
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.Formatting = Formatting.Indented;
            if (newNames)
            {
                settings.ContractResolver = new CustomNamesContractResolver();
            }
    
            return JsonConvert.DeserializeObject<T>(text, settings);
        }
    }
    class CustomNamesContractResolver : DefaultContractResolver
    {
        protected override IList<JsonProperty> CreateProperties(System.Type type, MemberSerialization memberSerialization)
        {
            // Let the base class create all the JsonProperties 
            // using the short names
            IList<JsonProperty> 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

    0 讨论(0)
  • 2020-12-01 22:36

    Define different configuration modes like Debug/Release/QA/Staging

    Then add compilation symbols for each one of them. and in your code you do something like:

    Following I suppose you defined: QA and STAGING

    public class Customer
    {
    
        [JsonProperty(PropertyName = "email")]          
        public string Email { get; set; }
    
        #if QA
            [JsonProperty(PropertyName = "prop[QA_ID]")]
        #elif STAGING
            [JsonProperty(PropertyName = "prop[STAGING_ID]")]
        #endif
        public string Test{ get; set; }
    
        // there are lot of properties 
    }
    

    You can use these configuration for automated deploy too which will save you time.

    0 讨论(0)
提交回复
热议问题