我试图使用 System.Dynamic.ExpandoObject 这样我就可以动态地在运行时创建的属性。后来,我需要通过这个对象的实例和所使用的机制需要序列化。
当然,当我试图序列化我的动态对象,我得到异常:
System.Runtime.Serialization.SerializationException是未处理的。的
的组件类型System.Dynamic.ExpandoObject'System.Core程序,版本= 4.0.0.0,文化=中性公钥= b77a5c561934e089'未标记为可序列化。的
我可以序列化ExpandoObject?是否有另一种方法来创建一个动态的对象是可序列化?也许使用DynamicObject包装器?
我创建了一个非常简单的Windows窗体的例子复制的错误:
使用系统; 使用System.Windows.Forms的; 使用System.IO; 使用System.Runtime.Serialization; 使用System.Runtime.Serialization.Formatters.Binary; 使用System.Dynamic; 命名空间DynamicTest { 公共部分类Form1中:形态 { 公共Form1中() { 的InitializeComponent(); } 私人无效的button1_Click(对象发件人,EventArgs的) { 动态dynamicContext =新ExpandoObject(); dynamicContext.Greeting =你好; IFormatter格式化=新的BinaryFormatter(); 流流=新的FileStream(MyFile.bin,FileMode.Create, FileAccess.Write,FileShare.None); formatter.Serialize(流dynamicContext); stream.Close(); } } }解决方案
我不能序列ExpandoObject,但我可以手动序列化DynamicObject。因此,使用DynamicObject的TryGetMember / TrySetMember方法和实施ISerializable的,我可以解决我的问题,这是非常序列化动态对象。
我实现了我的简单测试程序如下:
使用系统; 使用System.Windows.Forms的; 使用System.IO; 使用System.Runtime.Serialization; 使用System.Runtime.Serialization.Formatters.Binary; 使用System.Collections.Generic; 使用System.Dynamic; 使用System.Security.Permissions; 命名空间DynamicTest { 公共部分类Form1中:形态 { 公共Form1中() { 的InitializeComponent(); } 私人无效的button1_Click(对象发件人,EventArgs的) { 动态dynamicContext =新DynamicContext(); dynamicContext.Greeting =你好; this.Text = dynamicContext.Greeting; IFormatter格式化=新的BinaryFormatter(); 流流=新的FileStream(MyFile.bin,FileMode.Create,FileAccess.Write,FileShare.None); formatter.Serialize(流dynamicContext); stream.Close(); } } [可序列化] 公共类DynamicContext:DynamicObject,ISerializable的 { 私人字典<字符串,对象> dynamicContext =新字典<字符串,对象>(); 公众覆盖布尔TryGetMember(GetMemberBinder粘合剂,out对象结果) { 返程(dynamicContext.TryGetValue(binder.Name,出结果)); } 公众覆盖布尔TrySetMember(SetMemberBinder粘结剂,对象值) { dynamicContext.Add(binder.Name,价值); 返回true; } [SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter =真) 公共虚拟无效GetObjectData使用(SerializationInfo中的信息,的StreamingContext上下文) { 的foreach(KeyValuePair<字符串,对象> KVP在dynamicContext) { info.AddValue(kvp.Key,kvp.Value); } } 公共DynamicContext() { } 保护DynamicContext(SerializationInfo中的信息,的StreamingContext上下文) { // TODO:反序列化之前验证输入。见msdn.microsoft/en-us/library/ty01x675(VS.80).aspx 的foreach(在信息SerializationEntry项) { dynamicContext.Add(entry.Name,entry.Value); } } } }和Why并SerializationInfo中没有TryGetValue方法?有缺少一块拼图,以保持它的简单。
I'm trying to use a System.Dynamic.ExpandoObject so I can dynamically create properties at runtime. Later, I need to pass an instance of this object and the mechanism used requires serialization.
Of course, when I attempt to serialize my dynamic object, I get the exception:
System.Runtime.Serialization.SerializationException was unhandled.
Type 'System.Dynamic.ExpandoObject' in Assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.
Can I serialize the ExpandoObject? Is there another approach to creating a dynamic object that is serializable? Perhaps using a DynamicObject wrapper?
I've created a very simple Windows Forms example to duplicate the error:
using System; using System.Windows.Forms; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Dynamic; namespace DynamicTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { dynamic dynamicContext = new ExpandoObject(); dynamicContext.Greeting = "Hello"; IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None); formatter.Serialize(stream, dynamicContext); stream.Close(); } } }解决方案
I can't serialize ExpandoObject, but I can manually serialize DynamicObject. So using the TryGetMember/TrySetMember methods of DynamicObject and implementing ISerializable, I can solve my problem which was really to serialize a dynamic object.
I've implemented the following in my simple test app:
using System; using System.Windows.Forms; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Collections.Generic; using System.Dynamic; using System.Security.Permissions; namespace DynamicTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { dynamic dynamicContext = new DynamicContext(); dynamicContext.Greeting = "Hello"; this.Text = dynamicContext.Greeting; IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None); formatter.Serialize(stream, dynamicContext); stream.Close(); } } [Serializable] public class DynamicContext : DynamicObject, ISerializable { private Dictionary<string, object> dynamicContext = new Dictionary<string, object>(); public override bool TryGetMember(GetMemberBinder binder, out object result) { return (dynamicContext.TryGetValue(binder.Name, out result)); } public override bool TrySetMember(SetMemberBinder binder, object value) { dynamicContext.Add(binder.Name, value); return true; } [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { foreach (KeyValuePair<string, object> kvp in dynamicContext) { info.AddValue(kvp.Key, kvp.Value); } } public DynamicContext() { } protected DynamicContext(SerializationInfo info, StreamingContext context) { // TODO: validate inputs before deserializing. See msdn.microsoft/en-us/library/ty01x675(VS.80).aspx foreach (SerializationEntry entry in info) { dynamicContext.Add(entry.Name, entry.Value); } } } }and Why does SerializationInfo not have TryGetValue methods? had the missing puzzle piece to keep it simple.
更多推荐
我可以序列化的.NET 4的ExpandoObject?
发布评论