1

i want to change the json property name dynamically and serialize the object.

here is my json for two different entities

For customer

{
  "userName": "66666",
  "password": "test1234",  
  "customersList": [
    {
      "address": "Test Stree2",
      "customerNumber": "US01-000281",
      "city": ""

    }
  ]
}

For contact

{
  "userName": "66666",
  "password": "test1234",  
  "contactList": [
    {
      "address": "Test stree1",
      "contactNumber": "US01-000281",
      "city": ""

    }
  ]
}

and the model that is holding this data is as follows

public class URequest<T>
    {

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string userName { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string password { get; set; }    

       [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public IList<T> requestList { get; set; }

    }

in above code requestList could contain list of contacts or customer but while sending i want to change the requestList json property name to respective entity name i.e. for customer it will be customerList and for contact it will be contactList after serializing.

7
  • 1
    A custom resolver may help you here , stackoverflow.com/questions/37917164/… Commented Jun 8, 2017 at 11:01
  • 1
    Your sample suggests that customer and contact are practically identical apart from labeling the identifier (customer-/contactNumber). Have you considered using a common entity and just add a type identifier? It would allow you to add more types ("lead", "superuser", etc.) without changing all your coding. Commented Jun 8, 2017 at 11:04
  • i have other class members too , just to simplify the example i have considered very few class members in both the models Commented Jun 8, 2017 at 11:08
  • Theoretically you could do it using the JsonConverter class, though I like @Filburt suggestion lots more :) Commented Jun 8, 2017 at 11:09
  • yes we can use JsonConveter but how thats the question :) Commented Jun 8, 2017 at 11:17

2 Answers 2

6

You can create a custom JsonConverter.

Using custom JsonConverter in order to alter the serialization of the portion of an object

Example

public class Customer
{
    public string Name { get; set; }
}

public class Client
{
    public string Name { get; set; }
}

public class URequest<T>
{

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string userName { get; set; }

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string password { get; set; }

    [JsonIgnore]
    public IList<T> requestList { get; set; }

}

public class URequestConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(URequest<T>));
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var objectType = value.GetType().GetGenericArguments()[0];
        URequest<T> typedValue = (URequest<T>) value;

        JObject containerObj = JObject.FromObject(value);

        containerObj.Add($"{objectType.Name.ToLower()}List", JToken.FromObject(typedValue.requestList));
        containerObj.WriteTo(writer);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

You can use it like this

    [TestMethod]
    public void TestMethod1()
    {
        URequest<Customer> request = new URequest<Customer>();
        request.password = "test";
        request.userName = "user";
        request.requestList = new List<Customer>();

        request.requestList.Add(new Customer() { Name = "customer" });

        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.Formatting = Formatting.Indented;
        settings.Converters.Add(new URequestConverter<Customer>());

        Console.WriteLine(JsonConvert.SerializeObject(request, settings));
    }
Sign up to request clarification or add additional context in comments.

4 Comments

i am getting error at GetGenericArguments()[0] it says type does not contain a definition for ` GetGenericArguments` and no extention method accepting a first argument of type 'Type'`
I have resolved an error using GetGenericTypeDefinition instead of GetGenericArguments , can tell us how we can handle plural words like instead of Contact i have 'Opportunity` so that needs to be Opportunities
And the problem is it adds one more duplicate block {"userName":"666666","password":"ABC","companyId":"US01","page":1,"type":null,"IdProperty":"Contact","requestList":[{"birthdate":"2017-06-09","city":"","contactId":0}],"Id":0,"contactsList":[{"birthdate":"2017-06-09","city":"","contactId":0}],"contactId":0}
@Hunt, containerObj.Remove removes the duplicate block.
4

using the ContentResolver i have solve the issue

here is the code

public class UserRequestResolver : DefaultContractResolver
{
    private string propertyName;

    public UserRequestResolver()
    {
    }
    public UserRequestResolver(string name)
    {
        propertyName = name;
    }
    public new static readonly UserRequestResolver Instance = new UserRequestResolver();

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        if (property.PropertyName == "requestList")
        {
            property.PropertyName = propertyName;              
        }
        return property;
     }
}

once can pass specific property name in the constructor.

JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.ContractResolver = new UserRequestResolver("contactList");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.