简体   繁体   中英

How to change property names when serializing to Json in asp.Net

I have an MVC Web API Controller that exposes a method:

    [HttpPost]
    public JsonResult<CustomClass> Details(RequestClass request)
    {
        var encoding = Encoding.GetEncoding("iso-8859-1");
        var settings = new Newtonsoft.Json.JsonSerializerSettings();
        return Json(_InputService.CustomClassGet(request.Id), settings, encoding);
    }

CustomClass is a really complex class wich contains several levels of objects of different classes. Objects from these classes are somehow built in another part of the code using a mapper that relies on Newtonsoft Json.

I just got a request to modify my code to change some of CustomClass property names (along the whole tree). My first approach was to create another set of classes, so I could have one for receiving data and other for exposing data with a converter in the middle but there are so many classes in the structure and they are so complex that it would consume a lot of effort. Also, during the process of converting from input to output classes, it would require twice the memory to hold 2 copies of the same exact data.

My second approach was using JsonProperty(PropertyName ="X") to change the resulting json BUT, as the input also relies in Newtonsoft Json, I completely broke the input process.

My next approach was to create a custom serializer and user [JsonConverter(typeof(CustomCoverter))] attribute BUT it changes the way CustomClass is serialized everywhere and I can't change the way the rest of the API responds, just some specific methods.

So, the question is... does anyone imagine a way to change the way my CustomClass is serialized just in certain methods ?

This is the final solution:

1) Created a custom Attribute and decorated the properties that I needed its name changed in the serialized Json:

[AttributeUsage(AttributeTargets.Property)]
class MyCustomJsonPropertyAttribute : Attribute
{
    public string PropertyName { get; protected set; }

    public MyCustomJsonPropertyAttribute(string propertyName)
    {
        PropertyName = propertyName;
    }
}

2) Decordated the properties accordingly

class MyCustomClass
{
    [MyCustomJsonProperty("RenamedProperty")]
    public string OriginalNameProperty { get; set; }
}

3) Implemented a Custom Resolver using reflection to remap the property name for those properties decorated with MyCustomJsonPropertyAttribute

class MyCustomResolver : DefaultContractResolver
{               
    public MyCustomResolver()
    {            
    }

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

        var attr = member.GetCustomAttribute(typeof(MyCustomJsonPropertyAttribute));
        if (attr!=null)
        {
            string jsonName = ((MyCustomJsonPropertyAttribute)attr).PropertyName;
            prop.PropertyName = jsonName;
        }
        return prop;
    }

}

4) Implemented the method in the controller like this:

    [HttpPost]
    public JsonResult<MyCustomClass> Details(RequestClass request)
    {
        var encoding = Encoding.GetEncoding("iso-8859-1");
        var settings = new Newtonsoft.Json.JsonSerializerSettings()
        {
            ContractResolver = new MyCustomResolver()
        };
        return Json(_InputService.CustomClassGet(request.Id), settings, encoding);
    }

Thanks a lot to dbc for pointing me the way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM