Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overwrite Json property name in c#

Tags:

json

c#

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 Customer
    {
        [JsonProperty(PropertyName = "email")]
        public string Email { get; set; }

        [JsonProperty(PropertyName = "prop[listId]")]
        public string Test{ get; set; }

        // there are lot of properties 
    }

In the property name Test ,external API service call required some thing like following json filed name format.

prop[7]

In my case this 7 can be changed according the environment like test,dev and prod.So what I'm looking for a way to move that listId value into app.config .

I have tried to do it as follow but it is not allowed to do that.for the listIdValue if assign the constant value it will work.

     private string listIdValue = ConfigurationManager.AppSettings["ListIdValue"];

     [JsonProperty(PropertyName = "prop["+listIdValue +"]")]
     public string Test{ get; set; }
like image 261
Thilina H Avatar asked Nov 12 '14 09:11

Thilina H


People also ask

What is JSON property name?

Specifies the property name that is present in the JSON when serializing and deserializing.

What is Jsonproperty annotation C#?

JsonPropertyAttribute indicates that a property should be serialized when member serialization is set to opt-in. It includes non-public properties in serialization and deserialization. It can be used to customize type name, reference, null, and default value handling for the property value.

What is JsonSerializerSettings?

Specifies the settings on a JsonSerializer object. Newtonsoft.Json. JsonSerializerSettings. Namespace: Newtonsoft.Json.


Video Answer


2 Answers

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 = "[email protected]", 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": "[email protected]",
  "Test": "asdasd"
}
{
  "email": "[email protected]",
  "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

like image 124
Mark Segal Avatar answered Oct 12 '22 04:10

Mark Segal


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.

like image 25
dariogriffo Avatar answered Oct 12 '22 06:10

dariogriffo