Silverlight程序集中定义的类型的二进制序列化

时间:2010-11-20 09:19:20

标签: silverlight serialization

我有一个silverlight程序集,由silverlight应用程序和ASP.Net应用程序引用。

在ASP.Net应用程序中,我需要序列化(二进制)Silverlight程序集中定义的一些类型实例。谁能帮我这个?

修改

我的问题是我有一个silverlight程序集,由一个银色应用程序,一个asp.net应用程序和一个winforms应用程序,在我的asp.net应用程序和winforms应用程序中使用我需要序列化共享silverlight中定义的类型

还有一个稍微不同的说明可以解释为什么需要这个属性?

4 个答案:

答案 0 :(得分:1)

  

也可以稍微不同的说明   有人解释了为什么这个属性   需要的?

让我们看看: 在序列化期间,BinaryFormatter调用FormatterServices类的方法。其中一个是

private static MemberInfo[] InternalGetSerializableMembers(RuntimeType type)

此方法包含下一个代码:

 if (!CheckSerializable(type))
    {
        throw new SerializationException(Environment.GetResourceString("Serialization_NonSerType", new object[] { type.FullName, type.Module.Assembly.FullName }));
    }

让我们检查FormatterServices类的CheckSerializable方法:

private static bool CheckSerializable(RuntimeType type)
{
    return type.IsSerializable;
}

此代码类似于:

    Type t = typeof (SomeClass);
    bool isTypeSerializable = t.IsSerializable;

在此示例中,如果类SomeClass具有Seri​​alizableAttribute,则isTypeSerializable将为true。否则是假的 Soo ...简单回答:此属性为标志,表示可以序列化类的实例。所以它只是需要而且都是。

关于你的主要问题:
遗憾的是,您不能直接使用二进制格式化程序来定义Silverlight程序集中定义的类 使用代理类的一种方法。
例如:
Silverlight组件内的类:

public class SomeClass
{
    public int IntValue { get; set; }
    public string StringValue { get; set; }
    public bool BoolValue { get; set; }
}

参考silverlight程序集支持常见.NET内部序列化的代理类:

    [Serializable]
    public class SomeClassProxy
    {
        public int IntValue { get; set; }
        public string StringValue { get; set; }
        public bool BoolValue { get; set; }

        public static SomeClassProxy GetSerializableObject(SomeClass silverlightClass)
        {
            return new SomeClassProxy
                    {
                        IntValue = silverlightClass.IntValue,
                        StringValue = silverlightClass.StringValue,
                        BoolValue = silverlightClass.BoolValue
                    };
        }

        public static SomeClass DeserializeSilverlightCompatible(Stream stream)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            SomeClassProxy proxy = formatter.Deserialize(stream) as SomeClassProxy;

            return new SomeClass
            {
                IntValue = proxy.IntValue,
                StringValue = proxy.StringValue,
                BoolValue = proxy.BoolValue
            };
        }
    }

因此,在您的asp .net或winforms应用程序中,您应该使用代理类操作:

    using(MemoryStream memoryStream = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
                            //create instance of silverlight class
            SomeClass mySilverlightClass = new SomeClass();
            mySilverlightClass.IntValue = 555;
            mySilverlightClass.StringValue = "Hello World!";
            mySilverlightClass.BoolValue = true;

            //<===serialize and take care of silverlight instance
            formatter.Serialize(memoryStream, SomeClassProxy.GetSerializableObject(mySilverlightClass));

            memoryStream.Seek(0, SeekOrigin.Begin);
            //===>deserialize to silverlight instance
            SomeClass mySilverlightClassRestored =  SomeClassProxy.DeserializeSilverlightCompatible(memoryStream);
        }

所以这个代理关注序列化和反序列化(在反序列化之后,你将收到在Silverlight程序集中定义的类SomeClass的实例)。

如果二进制格式化程序是软rescriction,那么我可能会建议您使用xml序列化程序:

XmlSerializer s = new XmlSerializer(typeof(SomeClass));
s.Serialize(memoryStream, mySilverlightClass);
memoryStream.Seek(0, SeekOrigin.Begin);
SomeClass restored = s.Deserialize(memoryStream) as SomeClass;

这种情况下不需要SerializableAttribute。

答案 1 :(得分:0)

您可以使用#if指令包含非Silverlight构建的序列化属性(和代码):

#if !SILVERLIGHT
[Serializable]
#endif
public class SomeClass
{
}

答案 2 :(得分:0)

您可以尝试我的序列化程序,它能够在.NET和Silverlight之间移动二进制数据...... http://whydoidoit.com

答案 3 :(得分:0)

我使用了一个名为sharp serializer的东西,它能够在没有可序列化属性的情况下二进制序列化类型。