【发布时间】:2016-11-17 15:03:18
【问题描述】:
我收到了错误
序列化器一旦生成就不能改变类型
尝试使用 Protobuff.net 进行序列化时。我已设法减少代码以找到罪魁祸首,但想知道为什么它无法序列化此属性。
我找到了一个我可以使用的有效解决方案,但我对解释此代码失败的原因很感兴趣。
不会序列化:
[ProtoContract]
public class SomeController
{
[ProtoMember(3)]
public int ControllerValue { get; set; }
[ProtoMember(4, AsReference = true)]
private ITest ITestObj { get; set; }
private SomeController(){}
public SomeController(object something, int value)
{
ControllerValue = value;
ITestObj = something as ITest;
}
}
将序列化:
错误是由SomeController.ITestObj 引起的。如果我将此类更改为:
[ProtoContract]
public class SomeController
{
[ProtoMember(3)]
public int ControllerValue { get; set; }
[ProtoMember(4, AsReference = true)]
private TestObj OriginalObject { get; set; }
private ITest ITestObj => OriginalObject as ITest;
private SomeController(){}
public SomeController(TestObj something, int value)
{
ControllerValue = value;
OriginalObject = something;
}
}
效果很好。
工作代码:
下面是一个独立的 HTTP 处理程序,它将运行此代码并重现错误:
using System.IO;
using System.Web;
using ProtoBuf;
namespace Handlers
{
/// <summary>
/// Summary description for Test
/// </summary>
public class Test : IHttpHandler
{
[ProtoContract]
public class TestObj : ITest
{
[ProtoMember(1, AsReference = true)]
public SomeController SomeController { get; set; }
[ProtoMember(2)]
public int SomeValue { get; set; }
private TestObj(){}
public TestObj(int something)
{
SomeController = new SomeController(this, something + 1);
SomeValue = something;
}
}
[ProtoContract]
public class SomeController
{
[ProtoMember(3)]
public int ControllerValue { get; set; }
[ProtoMember(4, AsReference = true)]
private ITest ITestObj { get; set; }
private SomeController() { }
public SomeController(object something, int value)
{
ControllerValue = value;
ITestObj = something as ITest;
}
}
[ProtoContract]
[ProtoInclude(5, typeof(TestObj))]
public interface ITest
{
[ProtoMember(6, AsReference = true)]
SomeController SomeController { get; set; }
[ProtoMember(7)]
int SomeValue { get; set; }
}
public void ProcessRequest(HttpContext context)
{
var testObj = new TestObj(5);
var serialised = Serialiser.Serialise(testObj);
var deserialised = Serialiser.Deserialise<TestObj>(serialised);
HttpContext.Current.Response.Write(deserialised.SomeValue + "|" + deserialised.SomeController.ControllerValue + "<br>");
}
protected internal class Serialiser
{
protected internal static byte[] Serialise<T>(T objectToSerialise)
{
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, objectToSerialise);
return stream.ToArray();
}
}
protected internal static T Deserialise<T>(byte[] bytes)
{
using (var stream = new MemoryStream(bytes))
{
return Serializer.Deserialize<T>(stream);
}
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
【问题讨论】:
-
您发布的代码(“它将运行此代码并重现错误”)对我来说很好,没有任何错误;我看到
5|6。你能告诉我你用的是什么版本吗?什么运行时? -
@MarcGravell 道歉,发布的代码是针对固定解决方案的。已将其更新为损坏的。使用 Protobuff.net 版本 2.1.0.0 运行时版本 v4.0.30319。如果对象被正确序列化/反序列化,则 5|6 是预期的输出。
标签: c# serialization protocol-buffers protobuf-net