我有以下使用svcutils.exe应用程序从xsd自动生成的C#代码示例。
[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; }
}
以下是单元测试,尝试将示例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扩展为自定义句柄枚举?或者也许有更好的方法来做到这一点?
答案 0 :(得分:6)
此行为按设计。以下是Enumerations and JSON paragraph on MSDN:
的引用枚举成员值被视为JSON中的数字,即 不同于它们在数据合同中的处理方式 作为会员名称加入。
此外,DataContractJsonSerializer会自动序列化所有枚举,因此EnumMemberAttribute实际上会被忽略。
对于解决方法,请查看this answer on SO。
答案 1 :(得分:0)
这是工作:
var ret = new JavaScriptSerializer().Deserialize<tblGridProjects>(retApi.Item2);
但是您无法使用数据名称属性,因此无法重命名属性。 您必须设置Json发送的属性名称。