我正在使用 protobuf-net 来序列化和反序列化我的消息。我的消息还包含可以为空的字符串。但是,当我在另一侧反序列化它们时,我得到空字符串 ("")。
根据谷歌文档,空字符串中字符串类型的默认值。这个问题的解决方案是什么?
这是我正在使用的代码:
Command message = new Command();
message.s_value = null;
using (MemoryStream stream = new MemoryStream())
{
Serializer.Serialize<Command>(stream, message);
stream.Close();
}
Run Code Online (Sandbox Code Playgroud)
反序列化同一个流后,我得到 s_value = ""
我有一些使用 Protobuf.net 的相当简单的代码,它抛出了一个非常奇怪的异常。在第 167 行的 MetaType.cs 中,它抛出 InvalidOperationException “一旦生成序列化程序,就无法更改类型”。这是什么意思,我该如何解决?
我的代码如下所示:
这个方法开始所有的序列化:
while (!Parallel.For(0, 100, (i) =>
{
Widget w;
lock (f) { w = f.CreateWidget(); }
SerialiseWidget(w);
}).IsCompleted)
{
Thread.Sleep(10);
}
Run Code Online (Sandbox Code Playgroud)
非常简单,它只是在 Parallel 中遍历所有内容,并序列化 100 个小部件。
serialise 方法也很简单:
private byte[] SerialiseWidget(Widget w)
{
using (MemoryStream m = new MemoryStream())
{
Serializer.Serialize<PacketChunk>(m, w);
return m.ToArray();
}
}
Run Code Online (Sandbox Code Playgroud)
最后,小部件类如下所示:
[ProtoContract]
private class Widget
{
[ProtoMember(1)]
public int a;
[ProtoMember(2)]
public byte[] b;
[ProtoMember(3)]
public Thing c; //Thing is itself a protocontract
[ProtoMember(4)] …Run Code Online (Sandbox Code Playgroud) C#,如何使用ProtoBuf .NET序列化dataTable?我可以举个例子吗?
我有,List<HtmlAgilityPack.HtmlNode>但protobuf-net给我错误,它没有合同.当我没有源时,如何为它指定合同?它实际上说它无法推断出类型,但我认为这是因为我没有使用它的属性,对吗?
默认的二进制序列化程序也会抱怨,因为类型未标记为可序列化.
编辑:错误消息是:
Type is not expected, and no contract can be inferred: HtmlAgilityPack.HtmlNode
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用protobufs序列化一些类.我使用NuGet安装了protobuf-net,使用属性正确装饰了我的代码,一切运行良好.
但是,最终消息将在C#中创建,但在其他环境中消耗,因此我需要从C#创建.proto文件,或者 - 对我来说似乎更合理 - 从.proto文件创建C#代码.
无论我做什么,我都找不到安装在我电脑任何地方的ProtoGen.exe.我也找到了这个旧帖子,但是当我创建一个.proto文本文件时,没有发生任何类似的事情.手动添加ProtoBufTool也不起作用.
我错过了什么?
我有一个类似乎没有使用protobuf-net序列化,它似乎打破了我的类有一个引用自己的另一个实例.这是一个例子(从我的实际代码中大大简化):
[ProtoContract]
public sealed class Acorn
{
[ProtoMember(50)]
public string Investment;
[ProtoMember(51)]
public string Broker;
[ProtoMember(52)]
public Acorn DefaultTransferAcorn;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,它是对Acorn类中另一个似乎导致问题的Acorn类的引用.我在单声道中收到以下错误消息:
System.Reflection.TargetInvocationException:调用目标抛出了异常.---> ProtoBuf.ProtoException:检测到可能的递归(偏移量:4级):AcornTrail3.Acorn
这是protobuf-net的限制,还是有办法使这项工作?
我需要使用protobuf序列化/反序列化类.对于我的类的一些属性,我需要定义一个默认值.我通过设置属性的值来做到这一点.在某些情况下,此默认值会覆盖protobuf数据中的值.
这是一个演示:
public class Program
{
static void Main(string[] args)
{
var target = new MyClass
{
MyBoolean = false
};
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, target);
stream.Position = 0;
var actual = Serializer.Deserialize<MyClass>(stream);
//actual.MyBoolean will be true
}
}
}
[ProtoContract(Name = "MyClass")]
public class MyClass
{
#region Properties
[ProtoMember(3, IsRequired = false, Name = "myBoolean", DataFormat = DataFormat.Default)]
public Boolean MyBoolean { get; set; } = true;
#endregion
}
Run Code Online (Sandbox Code Playgroud)
反序列化数据后,MyBoolean的值为true.
我该如何解决这个问题?
当我尝试像 NetworkComms 示例所说的那样序列化对象时,我从 SendObject 方法收到此错误。这似乎有些愚蠢,但我不知道我需要做什么,而且我认为实现 IExplicitlySerialize 接口不是答案。这是我的调用方法和序列化类:
public static void SendTestPacket()
{
var message = "This is a test packet";
NetworkComms.SendObject("PacketPrintToConsole", "192.168.1.105", 5614, new PacketPrintToConsole(message));
}
[ProtoContract]
public class PacketPrintToConsole
{
[ProtoMember(1)]
public string Message { get; set; }
public PacketPrintToConsole() { }
public PacketPrintToConsole(string message)
{
this.Message = message;
}
}
Run Code Online (Sandbox Code Playgroud) 我在使用命名管道来回发送对象(双工通信)时遇到了麻烦。编码:
到:
[ProtoContract]
public class ServerResponse
{
[ProtoMember(1)]
public string FirstName { get; set; }
[ProtoMember(2)]
public string LastName { get; set; }
}
[ProtoContract]
public class ServerRequest
{
[ProtoMember(1)]
public string Name { get; set; }
[ProtoMember(2)]
public int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
服务器:
static void Main(string[] args)
{
Console.WriteLine("Starting Server");
StartServer();
Console.WriteLine("Press any key to stop server..");
Console.ReadKey();
}
static void StartServer()
{
Task.Factory.StartNew(() =>
{
var server = new NamedPipeServerStream("MyPipes");
server.WaitForConnection();
Console.WriteLine("Connected");
//StreamReader reader = …Run Code Online (Sandbox Code Playgroud) 我有几个包含不同 protobuf 文件的合同项目,但是某些消息类型具有相同的消息类型,例如
message user
{
Address address = 1
}
message Address
{
....
}
Run Code Online (Sandbox Code Playgroud)
我现在创建了一个共享项目并向其中添加了一个 Address.proto 文件,其中仅包含
syntax = "proto3"
option csharp_namespace = "shared.protos"
package AddressPackage
message Address {....}
Run Code Online (Sandbox Code Playgroud)
我的问题是弄清楚如何将其导入到我不同合同项目中的原型中。我已添加共享项目作为参考,但我从那里尝试的所有其他内容都导致错误。
我知道我需要使用import只是还没有弄清楚如何写字符串。
更新
我正在使用 gRPC.tools nuget 并且所有 .proto 文件都设置为 protobuf 编译器
文件结构如下
用户合同项目
两个项目都在它自己的文件夹中,并且这些文件夹彼此相邻。
在它说的共享项目中
<ItemGroup>
<None Remove="Protos\Address.proto" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\Address.proto">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Protobuf>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
并在 user.contract 中说
<ItemGroup>
<None Remove="Protos\User.proto" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\User.proto" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
提前致谢。