- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
BinaryFormatter 能够简单地处理序列化:
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-net 替换 BinaryFormatter 时:
using (var memoryStream = new MemoryStream())
{
Serializer.Serialize(memoryStream, token);
return memoryStream.ToArray();
}
我得到以下异常:
Type is not expected, and no contract can be inferred: System.IdentityModel.Tokens.SessionSecurityToken
我尝试添加:
RuntimeTypeModel.Default.Add(typeof(SessionSecurityToken), true);
它通过了异常,但我现在得到一个零字节数组。
如何正确配置 protobuf-net 以序列化 SessionSecurityToken?
另一方面,SessionSecurityToken 没有无参数构造函数。
using (var memoryStream = new MemoryStream(tokenAsBytes))
{
return Serializer.Deserialize<SessionSecurityToken>(memoryStream);
}
抛出一个 ProtoException:
No parameterless constructor found for SessionSecurityToken
BinaryFormatter
能够毫不费力地做到这一点:
using (var memoryStream = new MemoryStream(bytes))
{
var binaryFormatter = new BinaryFormatter();
return (SessionSecurityToken)binaryFormatter.Deserialize(memoryStream);
}
如何正确配置 protobuf-net 以反序列化 SessionSecurityToken?
最佳答案
protobuf-net 并没有声称能够序列化每一种类型;实际上,您很难通过大多数序列化程序(XmlSerializer
、任何 json 序列化程序、DataContractSerializer
等)对其进行序列化。 BinaryFormatter
属于不同的类别 序列化程序 - 在这种特殊情况下,通过 ISerializable.GetObjectData(SerializationInfo, StreamingContext)
实现自定义序列化。
构造函数是一个红色的鲱鱼;实际上,protobuf-net 可以完全绕过构造函数,在这个特定场景中,BinaryFormatter
通过 .ctor(SerializationInfo, StreamingContext)
使用自定义序列化构造函数。
对于简单的情况,protobuf-net 可以通过属性或运行时选项进行配置;对于更复杂的场景,surrogates 可用于在表示之间进行映射 - 然而,在这种情况下,我建议(查看 SessionSecurityToken
的实现)这比你可能想要维护。
我会在这里后退一两步;大多数序列化程序设计用于处理数据,而不是实现 - 并且与 DTO 等一起工作很好。SessionSecurityToken
非常不是 DTO,并且有不是在它们之间切换的简单方法。我的强烈建议是:序列化这代表的内容,而不是是的内容。但是,如果这是现有复杂模型的一部分并且真的很难分离出来,您可以为这些位切换回 BinaryFormatter
。我没有对此进行测试,但请考虑:
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() };
}
}
}
请记住,这只是将一个序列化程序的输出作为原始数据嵌入到另一个序列化程序中。幸运的是,protobuf-net 很乐意谈论二进制,所以这不会增加任何明显的开销(只是 blob 的 header 和长度前缀) - 但它也不会对 SessionSecurityToken< 做任何特别聪明或聪明的事情
实例。如果这是您正在序列化的唯一东西,那真的不值得。如果这只是更大的 DTO 模型中的一个丑陋的颠簸,其中大部分可以很好地序列化 - 那么它可能会为您完成工作。
关于c# - 如何配置 protobuf-net 的 RuntimeModel.Default 以支持序列化/反序列化 SessionSecurityToken?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17563554/
BinaryFormatter 能够简单地处理序列化: private byte[] TokenToBytes(SessionSecurityToken token) { if (token
我在 MSDN 论坛、Dominic Baier 的博客和其他来源中读到,DPAPI 无法在 Azure 中开箱即用,并且在任何类型的 Web 场场景中处理联合身份验证的一种方法是替换DPAPI 会使
我是一名优秀的程序员,十分优秀!