JavaScriptSerializer 与枚举转字符串:常见错误及如何避免

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么枚举序列化是每位 C# 开发者的痛点

\n\n

您是否遇到过这样的情况:您精心编写的、处理枚举 (enum) 的 C# 代码,突然开始输出奇怪的数字,而不是清晰的名称?如果是这样,您并不孤单。Stack Overflow 上关于“JavaScriptSerializer - JSON serialization of enum as string”的问题已经积累了数千次浏览,这意味着很多人都遇到过这个问题。

\n\n

让我们来弄清楚,为什么 JavaScriptSerializer 默认会将您漂亮的枚举名称变成无意义的数字,更重要的是,如何一劳永逸地解决这个问题。

\n\n

问题:为什么枚举会变成数字?

\n\n

默认情况下,JavaScriptSerializer(来自 System.Web.Script.Serialization 命名空间的类)会将枚举序列化为其整数值。这是因为每个枚举底层都是一个整数(默认为 int)。

\n\n
public enum Status\n{\n    Active = 1,\n    Inactive = 2,\n    Pending = 3\n}\n\npublic class Order\n{\n    public int Id { get; set; }\n    public Status OrderStatus { get; set; }\n}\n\n// 序列化\nvar order = new Order { Id = 1, OrderStatus = Status.Active };\nvar serializer = new JavaScriptSerializer();\nstring json = serializer.Serialize(order);\n// 结果: {"Id":1,"OrderStatus":1}\n
\n\n

您得承认,"OrderStatus":1 看起来信息量不足。想象一下,这样的 JSON 被发送到 API——客户端代码将不得不猜测数字 1 代表什么。

\n\n

使用 JavaScriptSerializer 和枚举时的 5 大错误

\n\n

错误 1:使用 EnumMemberAttribute 但未进行配置

\n\n

许多开发者尝试使用来自 System.Runtime.Serialization 命名空间的 [EnumMember],认为这能解决问题。但 JavaScriptSerializer 默认不处理此属性。

\n\n
[DataContract]\npublic enum Status\n{\n    [EnumMember(Value = "active")]\n    Active = 1,\n    [EnumMember(Value = "inactive")]\n    Inactive = 2\n}\n\n// JavaScriptSerializer 仍然会输出数字\n
\n\n

错误 2:忽略 ScriptIgnoreAttribute

\n\n

有些人试图隐藏枚举属性,然后单独添加一个字符串表示。这会使代码复杂化并破坏数据完整性。

\n\n

错误 3:通过 if/switch 手动转换

\n\n

最常见的“权宜之计”是创建一个额外的字符串属性并进行手动转换:

\n\n
public class Order\n{\n    public int Id { get; set; }\n    public Status OrderStatus { get; set; }\n    \n    // 数据重复——不良实践\n    public string OrderStatusString\n    {\n        get { return OrderStatus.ToString(); }\n    }\n}\n
\n\n

问题:现在您有了两个需要同步的属性。迟早它们会不一致。

\n\n

错误 4:忘记字符大小写

\n\n

即使您解决了序列化问题,客户端代码可能期望 "active",但收到的却是 "Active"。大小写差异会导致 JavaScript 端的错误。

\n\n

错误 5:使用过时的 JavaScriptSerializer 而非 Newtonsoft.Json

\n\n

在现代 .NET 版本中,JavaScriptSerializer 类已被视为过时。Microsoft 建议使用 System.Text.Json 或 Newtonsoft.Json。但如果您在处理遗留项目或 Web Forms,则无法避免使用它。

\n\n

如何正确地将枚举序列化为字符串:3 种可行的解决方案

\n\n

解决方案 1:自定义转换器(推荐方法)

\n\n

创建您自己的类,继承自 JavaScriptConverter,并将其注册到序列化器中。

\n\n
public class EnumToStringConverter<T> : JavaScriptConverter where T : struct\n{\n    public override IEnumerable<Type> SupportedTypes\n                

博客

书籍推荐