(MfA) -字典类型上CollectionDataContractAttribute的Name属性被忽略

本文关键字:Name 属性 CollectionDataContractAttribute MfA 字典 类型 | 更新日期: 2023-09-27 18:10:22

请注意,我在这里发布这个QA是为了帮助其他人,并作为Xamarin上的错误报告11881的合作伙伴。Android Bugzilla区域。因此,下面描述的类型仅用于演示目的。我已经发布了一个初步的答案,也参考了相同的错误报告,但希望在某些时候这个问题可以用"这已经在x.y版本中修复了"来"回答"。

我有一个在Mono Android和Windows RT源之间共享的类型:

[CollectionDataContract(Name = "MyDictionary", 
    Namespace = "http://foo.bar/schema", 
    ItemName = "pair", 
    KeyName = "mykey", 
    ValueName = "myvalue")]
public class MyDictionary : Dictionary<string, string>
{
}

这是从我们的Web API(运行在Asp上)读取的。. Net Web API, Framework 4.5)作为XML,看起来像这样:

<MyDictionary 
 xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://foo.bar/schema">
  <pair>
    <mykey>message1</mykey>
    <myvalue>Hello</myvalue>
  <pair>
  <pair>
    <mykey>message2</mykey>
    <myvalue>World</myvalue>
  <pair>
</MyDictionary>

当如上所述使用类时,此XML在Windows, Windows Phone和Win-RT平台上正确反序列化。

然而,在Mono for Android构建中,我得到

System.Runtime.Serialization.SerializationException: Expected element 'ArrayOfpair' in namespace 'http://foo.bar/schema', but found Element node 'MyDictionary' in namespace 'http://foo.bar/schema' .

我做错了什么?

(MfA) -字典类型上CollectionDataContractAttribute的Name属性被忽略

假设我没有做错什么-我写了一个NUnitLight单元测试来测试MyDictionary的实例是否会被Mono for Android的DataContractSerializer实现正确序列化:

public string Serialize(object o)
{
  DataContractSerializer ser = new DataContractSerializer(o.GetType());
  using (var ms = new MemoryStream())
  {
    ser.WriteObject(ms, o);
    return Encoding.Default.GetString(ms.ToArray());
  }
}
[Test]
public void ShouldSerializeDictionaryCorrectlyAndDeserialize()
{
  MyDictionary dict = new MyDictionary();
  dict["message1"] = "hello";
  dict["message2"] = "world";
  var s = Serialize(dict);
  Assert.That(s, Is.StringStarting("<MyDictionary"));
}

单元测试失败,输出字符串以'ArrayOfpair'开头,而不是 'MyDictionary',这将与正确的 XML反序列化失败的原始行为一致,因为它没有启动'ArrayOfpair'。

因此,

这是DataContractSerializer的Mono for Android实现中的一个很好的错误候选(我在这里报告了这个错误)-但是在该错误得到确认和修复之前,将需要一个解决方案。在我的例子中,我已经分享了代码库问题(Android, Windows和Monotouch),所以我不想只是为Android重写这种类型。如果我想出了一个体面的解决办法,我会把它贴在这个答案上。

请注意-我还不知道这是否也适用于Monotouch -我们还没有一个完整的组件构建来运行相同的测试,所以它可能会,我只是不知道。