可以在.NET 4中序列化一个ExpandoObject吗? [英] Can I serialize an ExpandoObject in .NET 4?

查看:172
本文介绍了可以在.NET 4中序列化一个ExpandoObject吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用一个 System.Dynamic.ExpandoObject ,所以我可以在运行时动态创建属性。之后,我需要传递一个这个对象的实例,所用的机制需要序列化。

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未处理。

在Assembly中键入System.Dynamic.ExpandoObject System.Core,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089'未标记为可序列化。

我可以序列化ExpandoObject吗?是否有另一种创建可序列化的动态对象的方法?也许使用 DynamicObject wrapper?

Can I serialize the ExpandoObject? Is there another approach to creating a dynamic object that is serializable? Perhaps using a DynamicObject wrapper?

我创建了一个非常简单的Windows窗体示例来复制错误:

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();
        }
    }
}


推荐答案

我无法序列化ExpandoObject,但我可以手动序列化DynamicObject。所以使用DynamicObject的TryGetMember / TrySetMember方法并实现ISerializable,我可以解决我的问题,这真的是序列化动态对象。

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 http://msdn.microsoft.com/en-us/library/ty01x675(VS.80).aspx
            foreach (SerializationEntry entry in info)
            {
                dynamicContext.Add(entry.Name, entry.Value);
            }
        }

    }
}

为什么SerializationInfo不具有TryGetValue方法? a>有一个失踪的难题,以保持简单。

and Why does SerializationInfo not have TryGetValue methods? had the missing puzzle piece to keep it simple.

这篇关于可以在.NET 4中序列化一个ExpandoObject吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆