protobuf-net.Grpc 序列化接口
protobuf-net.Grpc serializing Interfaces
我在 Protobuf-net.grpc 中使用 CodeFirst 序列化接口时遇到了一些困难。它是 DataContract 中的一个 DataMember。当我在一个简单的控制台应用程序中使用它时它工作正常,但是当我尝试在具有相同引用的不同项目中使用它时,它不会序列化。当在 gRPC 服务器上完成 AddCodeFirst 时,我也可以在 Visual studio 输出中看到此错误:
Exception thrown: 'System.InvalidOperationException' in
protobuf-net.dll
这是我的项目和虚拟应用程序中的 DataContract 代码
using ProtoBuf;
namespace ProtoBufTesting.Prepare
{
[DataContract, ProtoContract]
public class ExtensionData
{
public ExtensionData() { }
public ExtensionData(
string extensionName,
string packageIdentifier,
IExtensionCertificateCollection collection)
{
this.ServiceName = extensionName;
this.PackageIdentifier = packageIdentifier;
this.CertificateCollection = collection;
}
[DataMember]
[ProtoMember(1)]
public string ServiceName
{
get; private set;
}
[DataMember]
[ProtoMember(4)]
public string PackageIdentifier
{
get; private set;
}
[DataMember]
[ProtoMember(5)]
public IExtensionCertificateCollection CertificateCollection { get; private set; }
}
}
这是 IExtensionCertificateCollection 接口,它具有在我的示例项目中工作的 ProtoContract 装饰器。
namespace ProtoBufTesting
{
[ProtoContract]
public interface IExtensionCertificateCollection
{
IExtensionCertificate GetByThumbprint(string thumbprint);
IEnumerable<IExtensionCertificate> AllCertificates { get; }
}
}
这是使用 ExtensionData 数据合约的服务合约
[ServiceContract(Namespace = "blah")]
public interface IRTC
{
[OperationContract]
ExtensionData PrepareExtension(PrepareExtensionInput input);
}
如果您在下面看到,这就是我进行 Code First 设置的方法。
除了在我做同样事情的第二个项目中,这工作得很好。我真的不确定如何调试它。我做一个示例控制台应用程序的原因是测试接口是否使用 ProtoContract 装饰器进行序列化并且它们仅使用 ProtoContract 装饰器就成功了......但是当我开始在一个更大的项目(相同的接口定义和数据契约)中使用它时,它只是似乎没有序列化 DataContract。当我从 Datamember 中删除该接口时,它只会序列化 DataContract。有什么想法我应该如何调试它以找出造成这种情况的原因吗?我已经坚持了几个小时。除了 InvalidOperationException,我在 VS 输出中没有看到任何其他错误。
Server server = new Server
{
Ports = { new ServerPort("localhost", ServerPort.PickUnused , ServerCredentials.Insecure) }
};
server.Services.AddCodeFirst(new RTC());
server.Start();
int port = server.Ports.Single().BoundPort;
Console.WriteLine("server listening on port " + port);
GrpcClientFactory.AllowUnencryptedHttp2 = true;
Channel channel = new Channel("localhost", port, ChannelCredentials.Insecure);
var rtc = channel.CreateGrpcService<IRTC>();
更新:
我想出了一个不同的方法来 'debug' 这个 - 使用下面的这个方法。它解析了我要序列化的对象的架构。对这个特定对象进行 try catch 至少给了我一个错误! “标签必须是正整数”。我发现了这个问题并修复了它。
ProtoBuf.Meta.RuntimeTypeModel.Default.GetSchema(typeof(ExtensionData));
但在那次错误之后,我仍然继续获取以前的静止图像,但似乎无法解决。我在单元测试方法下 运行 它只在 AddCodeFirst 期间显示像这样的高级错误 - 我在 AddCodeFirst 中添加了一个 TraceWriter,这就是它所说的 -
[warning] Type cannot be serialized; ignoring: ExtensionData
[warning] Signature not recognized for PrepareExtension; method will not be bound
我该如何进一步调查这个问题?这与我仍然得到的先前错误有关:
抛出异常:'System.InvalidOperationException' in protobuf-net.dll
我终于解决了这个问题。许多与接口(和其他接口)关联的类型没有被正确反序列化。我没有在任何错误日志中看到这一点,但这使得很难找到..在线搜索/通过代码隐藏查找protobuf-grpc..它看起来像是添加了需要反序列化的所有类型的显式注册需要接口,否则无法使用
我不知道是否有更好的方法来做到这一点,但这在 grPC AddCodeFirst 之前是必需的,否则服务不会在没有先完成此操作的情况下注册这些方法。
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(IExtensionCertificateCollection), true).AddSubType(1, typeof(ExtensionCertificateCollection));
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(IExtensionCertificateCollection), true).AddSubType(1, typeof(NewCollectionCerts));
server.Services.AddCodeFirst(new FakeRTC(), log: writelogs);
我在 Protobuf-net.grpc 中使用 CodeFirst 序列化接口时遇到了一些困难。它是 DataContract 中的一个 DataMember。当我在一个简单的控制台应用程序中使用它时它工作正常,但是当我尝试在具有相同引用的不同项目中使用它时,它不会序列化。当在 gRPC 服务器上完成 AddCodeFirst 时,我也可以在 Visual studio 输出中看到此错误:
Exception thrown: 'System.InvalidOperationException' in protobuf-net.dll
这是我的项目和虚拟应用程序中的 DataContract 代码
using ProtoBuf;
namespace ProtoBufTesting.Prepare
{
[DataContract, ProtoContract]
public class ExtensionData
{
public ExtensionData() { }
public ExtensionData(
string extensionName,
string packageIdentifier,
IExtensionCertificateCollection collection)
{
this.ServiceName = extensionName;
this.PackageIdentifier = packageIdentifier;
this.CertificateCollection = collection;
}
[DataMember]
[ProtoMember(1)]
public string ServiceName
{
get; private set;
}
[DataMember]
[ProtoMember(4)]
public string PackageIdentifier
{
get; private set;
}
[DataMember]
[ProtoMember(5)]
public IExtensionCertificateCollection CertificateCollection { get; private set; }
}
}
这是 IExtensionCertificateCollection 接口,它具有在我的示例项目中工作的 ProtoContract 装饰器。
namespace ProtoBufTesting
{
[ProtoContract]
public interface IExtensionCertificateCollection
{
IExtensionCertificate GetByThumbprint(string thumbprint);
IEnumerable<IExtensionCertificate> AllCertificates { get; }
}
}
这是使用 ExtensionData 数据合约的服务合约
[ServiceContract(Namespace = "blah")]
public interface IRTC
{
[OperationContract]
ExtensionData PrepareExtension(PrepareExtensionInput input);
}
如果您在下面看到,这就是我进行 Code First 设置的方法。 除了在我做同样事情的第二个项目中,这工作得很好。我真的不确定如何调试它。我做一个示例控制台应用程序的原因是测试接口是否使用 ProtoContract 装饰器进行序列化并且它们仅使用 ProtoContract 装饰器就成功了......但是当我开始在一个更大的项目(相同的接口定义和数据契约)中使用它时,它只是似乎没有序列化 DataContract。当我从 Datamember 中删除该接口时,它只会序列化 DataContract。有什么想法我应该如何调试它以找出造成这种情况的原因吗?我已经坚持了几个小时。除了 InvalidOperationException,我在 VS 输出中没有看到任何其他错误。
Server server = new Server
{
Ports = { new ServerPort("localhost", ServerPort.PickUnused , ServerCredentials.Insecure) }
};
server.Services.AddCodeFirst(new RTC());
server.Start();
int port = server.Ports.Single().BoundPort;
Console.WriteLine("server listening on port " + port);
GrpcClientFactory.AllowUnencryptedHttp2 = true;
Channel channel = new Channel("localhost", port, ChannelCredentials.Insecure);
var rtc = channel.CreateGrpcService<IRTC>();
更新:
我想出了一个不同的方法来 'debug' 这个 - 使用下面的这个方法。它解析了我要序列化的对象的架构。对这个特定对象进行 try catch 至少给了我一个错误! “标签必须是正整数”。我发现了这个问题并修复了它。
ProtoBuf.Meta.RuntimeTypeModel.Default.GetSchema(typeof(ExtensionData));
但在那次错误之后,我仍然继续获取以前的静止图像,但似乎无法解决。我在单元测试方法下 运行 它只在 AddCodeFirst 期间显示像这样的高级错误 - 我在 AddCodeFirst 中添加了一个 TraceWriter,这就是它所说的 -
[warning] Type cannot be serialized; ignoring: ExtensionData
[warning] Signature not recognized for PrepareExtension; method will not be bound
我该如何进一步调查这个问题?这与我仍然得到的先前错误有关:
抛出异常:'System.InvalidOperationException' in protobuf-net.dll
我终于解决了这个问题。许多与接口(和其他接口)关联的类型没有被正确反序列化。我没有在任何错误日志中看到这一点,但这使得很难找到..在线搜索/通过代码隐藏查找protobuf-grpc..它看起来像是添加了需要反序列化的所有类型的显式注册需要接口,否则无法使用
我不知道是否有更好的方法来做到这一点,但这在 grPC AddCodeFirst 之前是必需的,否则服务不会在没有先完成此操作的情况下注册这些方法。
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(IExtensionCertificateCollection), true).AddSubType(1, typeof(ExtensionCertificateCollection));
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(IExtensionCertificateCollection), true).AddSubType(1, typeof(NewCollectionCerts));
server.Services.AddCodeFirst(new FakeRTC(), log: writelogs);