通过装饰覆盖一个特定枚举的全局 Json.NET 枚举处理

Bri*_*Rak 7 asp.net-mvc serialization json json.net

我有一堆枚举,我希望 Json.NET 将它们序列化为驼峰式字符串。我的 Global.asax.cs 文件中有以下内容,并且运行良好:

HttpConfiguration config = GlobalConfiguration.Configuration;
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter { CamelCaseText = true });
Run Code Online (Sandbox Code Playgroud)

这使它成为这样的枚举:

public enum FavoriteWebSite {
    StackOverflow,
    GoogleNews
    // Etc
}
Run Code Online (Sandbox Code Playgroud)

将序列化为“stackOverflow”、“googleNews”等值。

但是,我有几个枚举是按位掩码。举一个简单的例子,假设一个看起来像这样:

public enum Hobbies {
    Walking = 0x01,
    Biking = 0x02,
    // Etc
}
Run Code Online (Sandbox Code Playgroud)

当我序列化这个枚举的实例时会发生什么取决于它里面有什么样的值。例如:

Hobbies set1 = Hobbies.Walking;                  // Serializes as "walking" -- bad
Hobbies set2 = Hobbies.Walking | Hobbies.Biking; // Serializes as "3"       -- good!
Run Code Online (Sandbox Code Playgroud)

我想覆盖此枚举上的序列化以仅将其序列化为 int,同时保留全局设置以完整使用驼峰式字符串。

我尝试删除全局配置,以便默认情况下将枚举序列化为整数,然后仅添加[JsonConverter(typeof(StringEnumConverter))]到非位掩码枚举。但是,这会导致 PascalCased,而不是 CamelCased 序列化。在像上面这样的方法装饰中使用 StringEnumConverter 时,我没有看到任何方法来设置 CamelCaseText 属性。

所以,回顾一下,目标是:

  1. 将单值枚举序列化为 pascalCased 字符串。
  2. 将位掩码枚举序列化为整数。

谢谢!

dbc*_*dbc 5

您的主要困难似乎是您没有用 装饰您的标志枚举FlagsAttribute,如下所示:

[Flags]
public enum Hobbies
{
    Walking = 0x01,
    Biking = 0x02,
    // Etc
}
Run Code Online (Sandbox Code Playgroud)

这是标志枚举的推荐最佳实践

设计标志枚举

? 务必将System.FlagsAttribute应用于标志枚举。不要将此属性应用于简单的枚举。

另请参见此处。如果不这样做,许多与枚举相关的 .Net 实用程序可能无法按预期用于标志枚举。

完成此操作后,StringEnumConverter会将具有复合值的标志枚举序列化为一组逗号分隔值,而不是您当前看到的数值:

{
  "Hobbies": "walking, biking"
}
Run Code Online (Sandbox Code Playgroud)

如果您不希望这样并且仍然希望看到 JSON 中标志枚举的默认数字值,您可以子类化StringEnumConverter以仅转换非标志枚举:

[Flags]
public enum Hobbies
{
    Walking = 0x01,
    Biking = 0x02,
    // Etc
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new NonFlagStringEnumConverter  { CamelCaseText = true });
Run Code Online (Sandbox Code Playgroud)

这将导致 Json.NET 回退到枚举的任何全局默认JSON 转换器,或者如果没有适用的回退,则回退到数字序列化。演示小提琴 #1在这里

此外,如果您需要取代在更高级别应用的转换器并强制标志枚举的数字序列化,请使用以下内容:

{
  "Hobbies": "walking, biking"
}
Run Code Online (Sandbox Code Playgroud)

演示小提琴 #2在这里