【问题标题】:How to change property names when serializing to Json in asp.Net在asp.Net中序列化为Json时如何更改属性名称
【发布时间】:2017-10-19 16:36:44
【问题描述】:

我有一个公开方法的 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 但是,由于输入也依赖于 Newtonsoft Json,我完全破坏了输入过程。

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

所以,问题是……有没有人想出一种方法来改变我的CustomClass 仅在某些方法中被序列化的方式

【问题讨论】:

  • Json.Net 可以读取一些非常复杂的类,我觉得奇怪的是 Newtonsoft.Json 库无法正确序列化。您确定复杂性是原因吗?您能否更详细地定义问题。
  • 使用自定义合约解析器。见JSON.net ContractResolver vs. JsonConverter
  • 其实这个问题是JSON.net ContractResolver vs. JsonConverter的重复吗?如果没有一些示例类型,我们无法通过代码提供更具体的答案。

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


【解决方案1】:

这是最终的解决方案:

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为我指路。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多