Silverlight:DataContractSerializer 无法处理只读集合属性
对于我们的 Silverlight 项目 (SL4),我使用的模型可能包含列表 (IList
)。根据良好实践和规则 CA2227:CollectionPropertiesShouldBeReadOnly IList
属性没有公共设置器。我们使用正在运行的 DataContractSerializer 序列化模型。但是当我尝试反序列化时,DataContractSerializer 的 ReadObject(Stream) 方法抛出 SecurityException,抱怨无法设置目标属性(指向 IList 属性),因为失踪的公共二传手。
由于 DataContractSerializer
是密封的,既不可扩展也不灵活,所以我目前没有机会添加某种额外的规则,允许使用 ILists
上的 foreach 循环反序列化 ILists
code>Add() 方法或其他传输集合项的方法。
我还尝试深入研究 DataContractSerializer 源(使用 Reflector)来创建一个小分叉,但看起来我必须深入挖掘并且复制整个序列化类似乎并不容易可行的解决方案。
您是否还有机会使用 DataContractSerializer 在没有公共 setter 的情况下序列化 List?
预先非常感谢您的想法!
更新
使用 XmlSerializer 解决。
托马斯
For our Silverlight Project (SL4) I'm using a Model which might contain Lists (IList<AnotherModel>
). According to good practice and rule CA2227:CollectionPropertiesShouldBeReadOnly
the IList
properties don't have a public setter. We serialize the Model using the DataContractSerializer which is working. But when I try to deserialize, a SecurityException is thrown by DataContractSerializer's ReadObject(Stream)
Method, complaining that the target property (pointing to the IList
property) cannot be set due to a missing public setter.
Since the DataContractSerializer
is sealed and neither extendable nor flexible so I currently see no chance to add some kind of additional rules which allow to deserialize the ILists
using a foreach-loop on Add()
method or some other method of transferring the collection items.
I've also tried to dig into DataContractSerializer
source (using Reflector) to create a little fork but it looks like i'd have to dig very deep and replicating whole serialization classes doesn't seem to be a viable solution.
Do you see another chance to serialize a List with no public setter using the DataContractSerializer
?
Thank you very much in advance for your ideas!
UPDATE
Solved using XmlSerializer.
Thomas
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用具体(可变)类型并为 DCS 提供它想要的东西。
它对我来说效果很好(我通常仅在 DataContractSerialized 类中指定具体类型)。通用序列化的整个方法是一种清洗,并且带有警告——选择你的战斗。或者,使用另一种方法,例如 ISerialized (uhg)。
Use concrete (mutable) types and give DCS what it wants.
It works well for me (I usually only specify concrete types in DataContractSerializable classes). The entire approach of generic serialization is a wash and comes with cavaets -- pick your battles. Alternatively, use another approach such as ISerializable (uhg).
在我们的例子中,我们发现我们并没有严格绑定到
DataContractSerializer
,有趣的是,XmlSerializer
确实支持只读序列化我列表!事实上,在这种情况下,它甚至不允许 IList 接口的公共设置器(无法反序列化接口属性),但(反)序列化 ILists 项目就像一个魅力。对我们来说唯一的改变是除了
[KnownType]
之外添加[XmlInclude]
属性(当然,替换DataContractSerializer.WriteObject(... )
到XmlSerializer.Serialize(...)
感谢您的支持!
In our case, we found out that we were not strictly bound to the
DataContractSerializer
, and interestingly, theXmlSerializer
DOES support serialization of read-only ILists! In fact, it even doesn't allow a public setter for the IList interface in this case (cannot deserialize interface property) but (de-)serializing the ILists items works like a charm.Only change for us was adding
[XmlInclude]
attributes in addition to[KnownType]
(and of course, replacing the few lines fromDataContractSerializer.WriteObject(...)
toXmlSerializer.Serialize(...)
.Thanks for your support! =)