如何配置protobuf网的RuntimeModel.Default支持序列化/反序列化SessionSecurityToken? [英] How do you configure protobuf-net's RuntimeModel.Default to support serializing/deserializing a SessionSecurityToken?

查看:469
本文介绍了如何配置protobuf网的RuntimeModel.Default支持序列化/反序列化SessionSecurityToken?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

BinaryFormatter的是能够处理系列化简单:

BinaryFormatter is able to handle serialization simply:

private byte[] TokenToBytes(SessionSecurityToken token)
{
    if (token == null)
    {
        return null;
    }

    using (var memoryStream = new MemoryStream())
    {
        var binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(memoryStream, token);
        return memoryStream.ToArray();
    }
}

当我试图与protobuf网替换的BinaryFormatter:

When I tried replacing BinaryFormatter with protobuf-net:

using (var memoryStream = new MemoryStream())
{
    Serializer.Serialize(memoryStream, token);
    return memoryStream.ToArray();
}



我得到了以下异常:

I get the following exception:

类型不是预期,并且没有合同可以推断出:
System.IdentityModel.Tokens.SessionSecurityToken

Type is not expected, and no contract can be inferred: System.IdentityModel.Tokens.SessionSecurityToken

我尝试添加:

RuntimeTypeModel.Default.Add(typeof(SessionSecurityToken), true);



它得到过去的例外,但我现在得到一个零字节数组。

Which gets past the exception but I now get a zero byte array.

如何正确配置protobuf网序列化SessionSecurityToken?

在不利的一面,SessionSecurityToken不有一个无参数的构造函数。

On the flipside, SessionSecurityToken does not have a parameterless constructor.

using (var memoryStream = new MemoryStream(tokenAsBytes))
{
    return Serializer.Deserialize<SessionSecurityToken>(memoryStream);
}



抛出一个ProtoException:

Throws a ProtoException:

没有发现SessionSecurityToken

No parameterless constructor found for SessionSecurityToken

的BinaryFormatter 是能够做到这一点没有任何大惊小怪:

BinaryFormatter is able to do it without any fuss:

using (var memoryStream = new MemoryStream(bytes))
{
    var binaryFormatter = new BinaryFormatter();
    return (SessionSecurityToken)binaryFormatter.Deserialize(memoryStream);
}



如何正确配置protobuf网反序列化SessionSecurityToken?

推荐答案

protobuf网不声称能够序列化每一个类型;的确,你将有很大的困难序列化是通过大多数串行器(的XmlSerializer ,任何一个JSON序列化,的DataContractSerializer 等)。 的BinaryFormatter 是在不同的类别的序列化 - 在这种特殊情况下,通过实现自定义序列化ISerializable.GetObjectData(的SerializationInfo ,的StreamingContext)

protobuf-net does not claim to be able to serialize every single type; indeed, you would have great difficulty serializing that via most serializers (XmlSerializer, any of the json serializers, DataContractSerializer, etc). BinaryFormatter is in a different category of serializers - and in this particular case, implements custom serialization via ISerializable.GetObjectData(SerializationInfo, StreamingContext).

构造的是一个红色的鲱鱼;实际上,protobuf网可以绕过构造完全,而在此特定情形的BinaryFormatter 使用通过 .ctor(SerializationInfo中,的StreamingContext)的自定义序列化的构造函数

The constructor thing is a red herring; actually, protobuf-net can bypass constructors completely, and in this particular scenario BinaryFormatter is using a custom serialization constructor via .ctor(SerializationInfo, StreamingContext).

对于简单的情况下,protobuf网可以通过属性或运行时选项配置;更复杂的情况,的替代物的可以用来表示之间的映射 - 然而,在这种情况下,我建议(看实施 SessionSecurityToken ) ,这是更复杂的比你可能想保持

For simple cases, protobuf-net can be configured via attributes or runtime options; for more complex scenarios, surrogates can be used to map between representations - however, in this case I would suggest (looking at the implementation of SessionSecurityToken) that this is more complex than you probably want to maintain.

我会退后一步一两步这里;大多数串行的设计与的数据的工作,不是实施 - 和工作的伟大与DTO的等 SessionSecurityToken 非常多的不可以一个DTO,且有它们之间切换的简单方法。我在这里强烈建议是:序列化这是什么的表示的,不是它的的。但是,如果这是一个现有的复杂模型的一部分,是真的真的很难分离出来,你可以切换回的BinaryFormatter 对于那些位。我没有测试过这一点,但考虑:

I would step back a step or two here; most serializers are designed to work with data, not implementation - and work great with DTOs etc. SessionSecurityToken is very much not a DTO, and there is no simple way of switching between them. My strong suggestion here would be: serialize what this represents, not what it is. However, if this is part of an existing complex model and is really really hard to separate out, you could switch back to BinaryFormatter for those bits. I haven't tested this, but consider:

RuntimeTypeModel.Default.Add(typeof(SessionSecurityToken), false)
        .SetSurrogate(typeof(BinaryFormatterSurrogate<SessionSecurityToken>));

使用:

[ProtoContract]
public class BinaryFormatterSurrogate<T>
{
    [ProtoMember(1)]
    public byte[] Raw { get; set; }

    public static explicit operator T(BinaryFormatterSurrogate<T> value)
    {
        if(value==null || value.Raw == null) return default(T);
        using(var ms = new MemoryStream(value.Raw))
        {
            return (T)new BinaryFormatter().Deserialize(ms);
        }
    }
    public static explicit operator BinaryFormatterSurrogate<T>(T value)
    {
        object obj = value;
        if (obj == null) return null;
        using (var ms = new MemoryStream())
        {
            new BinaryFormatter().Serialize(ms, obj);
            return new BinaryFormatterSurrogate<T> { Raw = ms.ToArray() };
        }

    }
}

请在记住这只是嵌入1串作为在另一个原始数据的输出。幸运的是protobuf网是幸福的谈话二进制文件,因此这将不添加任何明显的开销(只是头和长度前缀为BLOB) - 但它也不会做什么特别聪明或聪明与 SessionSecurityToken 实例。如果这是你的序列化的只有的东西,真的是不值得的。如果这仅仅是一个丑陋的凸起在一个较大的DTO模型,其中大部分的可以的序列化很好 - 那么它可能会为你所做的工作。

Keep in mind that this simply embeds the output of one serializer as raw data inside another. Fortunately protobuf-net is happy talking binary, so this won't add any noticeable overhead (just the header and length-prefix for the blob) - but it also won't do anything particularly smart or clever with the SessionSecurityToken instances. If this is the only thing you are serializing, it really isn't worth it. If this is just one ugly bump in a larger DTO model, where most of it can serialize nicely - then it might get the job done for you.

这篇关于如何配置protobuf网的RuntimeModel.Default支持序列化/反序列化SessionSecurityToken?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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