如何在asp.Net中序列化为Json时更改属性名称

时间:2017-10-19 16:36:45

标签: c# asp.net json asp.net-mvc asp.net-web-api

我有一个公开方法的MVC Web API控制器:

    [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是一个非常复杂的类,它包含不同类的几个级别的对象。这些类中的对象以某种方式构建在代码的另一部分中,使用依赖于Newtonsoft Json的映射器。

我刚收到修改我的代码的请求,以更改一些CustomClass属性名称(沿整个树)。我的第一种方法是创建另一组类,所以我可以有一个用于接收数据和其他用于在中间使用转换器公开数据但是结构中有很多类而且它们非常复杂以至于会消耗很多努力。此外,在从输入类转换为输出类的过程中,需要两倍的内存来保存相同精确数据的2个副本。

我的第二种方法是使用JsonProperty(PropertyName ="X")更改生成的json BUT,因为输入也依赖于Newtonsoft Json,我完全打破了输入过程。

我的下一个方法是创建自定义序列化程序和用户[JsonConverter(typeof(CustomCoverter))]属性但它改变了CustomClass在任何地方序列化的方式,我无法改变其余API响应的方式,只是一些具体的方法。

所以,问题是...... 是否有人想象一种方法可以改变我的CustomClass在某些方法中被序列化的方式

1 个答案:

答案 0 :(得分:0)

这是最终解决方案:

1)创建了一个自定义属性,并在序列化的Json中修饰了我需要更改其名称的属性:

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

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

2)相应地破坏了属性

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

3)使用反射实现自定义解析器,以重新映射用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)在控制器中实现了这样的方法:

    [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);
    }

非常感谢dbc为我指路。