在序列化json时如何忽略JsonProperty(PropertyName =" someName")?

时间:2013-12-16 22:44:33

标签: c# json serialization json.net

我有一些使用ASP.Net MVC的C#代码,它使用Json.Net来序列化一些DTO。为了减少有效负载,我已经使用[JsonProperty(PropertyName =“shortName”)]属性在序列化期间使用更短的属性名称。

当客户端是另一个.Net应用程序或服务时,这非常有用,因为反序列化将对象层次结构重新组合在一起,使用更长的更友好的名称,同时保持实际的传输负载低。

当客户端通过浏览器访问javascript / ajax时,问题就出现了。它发出请求,并获取json ...但是json使用的是缩短的不太友好的名称。

如何让json.net序列化引擎以编程方式忽略[JsonProperty(PropertyName =“shortName”)]属性?理想情况下,我的MVC服务将在那里运行,通常使用缩短的属性名称进行序列化。当我的代码检测到特定参数时,我想使用较长的名称序列化数据并忽略[JsonProperty()]属性。

有什么建议吗?

谢谢,

凯文

2 个答案:

答案 0 :(得分:37)

使用自定义合约解析器可以非常轻松地完成此操作。以下是您需要的所有代码:

class LongNameContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(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)
        {
            prop.PropertyName = prop.UnderlyingName;
        }

        return list;
    }
}

以下是使用解析器的快速演示:

class Program
{
    static void Main(string[] args)
    {
        Foo foo = new Foo
        {
            CustomerName = "Bubba Gump Shrimp Company",
            CustomerNumber = "BG60938"
        };

        Console.WriteLine("--- Using JsonProperty names ---");
        Console.WriteLine(Serialize(foo, false));
        Console.WriteLine();
        Console.WriteLine("--- Ignoring JsonProperty names ---");
        Console.WriteLine(Serialize(foo, true));
    }

    static string Serialize(object obj, bool useLongNames)
    {
        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.Formatting = Formatting.Indented;
        if (useLongNames)
        {
            settings.ContractResolver = new LongNameContractResolver();
        }

        return JsonConvert.SerializeObject(obj, settings);
    }
}

class Foo
{
    [JsonProperty("cust-num")]
    public string CustomerNumber { get; set; }
    [JsonProperty("cust-name")]
    public string CustomerName { get; set; }
}

输出:

--- Using JsonProperty names ---
{
  "cust-num": "BG60938",
  "cust-name": "Bubba Gump Shrimp Company"
}

--- Ignoring JsonProperty names ---
{
  "CustomerNumber": "BG60938",
  "CustomerName": "Bubba Gump Shrimp Company"
}

答案 1 :(得分:1)

只想用Deserializer类“扩展” Brian的答案,

static T Deserialize<T>(string json)
{
    return JsonConvert.DeserializeObject<T>(json, new JsonSerializerSettings()
    {
        ContractResolver = new LongNameContractResolver()
    });
}