如何在.NET中自定义JSON枚举的反序列化?

我有以下示例C#代码,使用svcutils.exe应用程序从xsd自动生成。

[DataContract] public enum Foo { [EnumMember(Value = "bar")] Bar = 1, [EnumMember(Value = "baz")] Baz = 2 } [DataContract] public class UNameIt { [DataMember(Name = "id")] public long Id { get; private set; } [DataMember(Name = "name")] public string Name { get; private set; } [DataMember(Name = "foo")] public Foo Foo { get; private set; } } 

以下是unit testing,尝试将示例JSON文档反序列化为UNameIt类。

  [TestClass] public class JsonSerializer_Fixture { public const string JsonData = @"{ ""id"":123456, ""name"":""John Doe"", ""foo"":""Bar""}"; [TestMethod] public void DataObjectSimpleParseTest() { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(UNameIt)); MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(JsonData)); UNameIt dataObject = serializer.ReadObject(ms) as UNameIt; Assert.IsNotNull(dataObject); Assert.AreEqual(123456, dataObject.Id); Assert.AreEqual(Foo.Baz, dataObject.Foo); } } 

不幸的是,测试失败的原因如下:

System.Runtime.Serialization.SerializationException:反序列化MyNamespace.Units.UNameIt类型的对象时出错。 “Bar”值无法解析为“Int64”类型。

如果我更新我的JSON字符串以将Enum的字符串说明符替换为整数,则测试将通过,例如

 public const string JsonData = @"{ ""id"":123456, ""name"":""John Doe"", ""foo"":""1""}"; 

我没有更改提供的JSON的灵活性,所以我必须弄清楚如何在序列化时转换字符串Enum表示。 理想情况下,我想在不必更改自动生成类的情况下为此提供帮助,因为一旦我重新生成类,我就会失去我的更改。

我想知道是否可以将DataContractJsonSerializer扩展为自定义句柄枚举? 或者也许有更好的方法来做到这一点?

此行为是设计使然 。 以下是MSDN上Enumerations和JSON段落的引用:

枚举成员值在JSON中被视为数字,这与在数据协定中处理它们的方式不同,它们作为成员名称包含在内。

此外, DataContractJsonSerializer将自动序列化所有枚举,因此实际上忽略了EnumMemberAttribute 。

有关解决方法 ,请查看SO上的此答案 。

这是工作:

 var ret = new JavaScriptSerializer().Deserialize(retApi.Item2); 

但是您不能使用datamembers属性,因此无法重命名属性。 您必须设置Json发送的属性名称。