我在Protobuf-net.grpc中使用CodeFirst序列化接口遇到了一些困难。它是DataMember中的DataContract。当我在一个简单的控制台应用程序中使用它时,它可以很好地工作,但是当我试图用相同的引用在不同的项目中使用它时,它不会序列化。当在Visual服务器上执行AddCodeFirst时,我也可以在Visual输出中看到这个错误:
引发的
异常: protobuf-net.dll中的“System.InvalidOperationException”
这是我的项目和虚拟应用程序中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 DataContract的服务契约。
[ServiceContract(Namespace = "blah")]
public interface IRTC
{
[OperationContract]
ExtensionData PrepareExtension(PrepareExtensionInput input);
}如果您看到下面的代码,我就这样做代码第一次设置。这是非常好的工作,除了在第二个项目,我在做同样的事情。我真的不知道如何去调试这个。我做了一个示例控制台应用程序的原因是为了测试接口是否使用ProtoContract装饰器序列化,他们成功地使用了ProtoContract装饰器.但是当我开始在更大的项目(相同的接口定义和数据契约)中使用它时,它似乎没有序列化DataContract。只有当我从数据成员中删除该接口时,它才会序列化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>();更新:
我想出了一种不同的“调试”方法--使用下面的方法。它解析了我试图序列化的对象的架构。使用这个特定的对象尝试捕获至少给了我一个错误!“标记必须是正整数”。我发现了这个问题并修复了它。
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我该如何进一步调查这件事?这与我仍然收到的前一个错误相链接:
引发的异常: protobuf-net.dll中的“System.InvalidOperationException”
发布于 2022-03-11 09:59:00
我终于解决了这个问题。许多与接口(和其他类型)关联的类型没有正确地反序列化。我在任何错误日志中都没有看到这个,这使得我很难找到。通过代码隐藏搜索在线/looking的protobuf-grpc.它看起来像添加所有类型的显式注册的所有类型,需要反序列化的接口是必需的,否则它将无法工作。
我不知道是否有更好的方法来做到这一点,但这是需要的,就在grPC AddCodeFirst there之前,如果没有首先注册这些方法,服务就不会注册这些方法。
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);https://stackoverflow.com/questions/71420086
复制相似问题