我将几个对象序列化为一个流,但是当我尝试将它们读回来时,除了最后一个对象之外我似乎无法得到任何东西:
ProtoBuf.Serializer.Serialize(stream, postA1);
ProtoBuf.Serializer.Serialize(stream, postB1);
stream.Position = 0;
var postA2 = ProtoBuf.Serializer.Deserialize<Post>(stream);
var postB2 = ProtoBuf.Serializer.Deserialize<Post>(stream);
Run Code Online (Sandbox Code Playgroud)
第一个反序列化将流移动到结尾,postA2包含postB1的值,而postB2只是一个未初始化的实例.这是预期的行为,如果是这样,您如何从流中的随机位置反序列化对象?
是否有一种首选方法可以在protobuf-net中序列化Guids?它似乎不是受支持的类型?
(注意:字典,其中T是一些ProtoContract/ProtoMembered类工作正常.)这个问题只发生在我的类型对象上.
我试图序列化词典工作字典.
typeof(object)不起作用.应该是?我应该实现基于字符串的解决方案吗?
在这种情况下,对象将只是一个.net原语.
[Test]
public void De_SerializeObjectDictionary2()
{
var d = new Dictionary<string, object>();
d.Add("abc", 12);
var ms = new MemoryStream();
var model = ProtoBuf.Meta.RuntimeTypeModel.Default;
//model.AutoAddMissingTypes = true;
//model.AutoCompile = true;
//model.InferTagFromNameDefault = true;
//model.Add(typeof (object), false);
//model.Add(typeof(Int32), true);
//model[typeof (object)].AddSubType(50, typeof (Int32));
model.Serialize(ms, d);
Serializer.Serialize<Dictionary<string,object>>(ms, d);
// <--- No serializer defined for type: System.Object
// or
//model.Add(typeof (object), false);
//Serializer.Serialize<Dictionary<string, object>>(ms, d);
//<-- Unexpected sub-type: System.Int32
ms.Position = 0;
var d2 = Serializer.Deserialize<Dictionary<string, object>>(ms);
}
Run Code Online (Sandbox Code Playgroud)
我试图提前定义这些类型......但我认为默认情况下它们是由protobuf-net处理的
//model.Add(typeof (object), …Run Code Online (Sandbox Code Playgroud) 我有一个WCF服务(.NET 4),它公开了4个端点,其中一个端点配置了protobuf-net(V1.0.0.280)行为扩展.但是,我注意到protobuf-net行为为所有已定义的端点启动,包括未配置的protbuf-net!我在下面粘贴了我的配置.我错过了什么吗?非常感谢任何帮助.. thx
<service name="MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint address="Http.Basic" binding="basicHttpBinding" bindingConfiguration="Http.Basic.Config" contract="IMyService" behaviorConfiguration="DefaultBehavior" />
<endpoint address="Http.Binary" binding="customBinding" bindingConfiguration="Http.Binary.Config" contract="IMyService" behaviorConfiguration="DefaultBehavior" />
<endpoint address="Tcp.Binary" binding="customBinding" bindingConfiguration="Tcp.Binary.Config" contract="IMyService" behaviorConfiguration="DefaultBehavior" />
<endpoint address="Http.ProtoBuf" binding="basicHttpBinding" bindingConfiguration="Http.Basic.Config" contract="IMyService" behaviorConfiguration="ProtoBufBehavior" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8085/MyService"/>
<add baseAddress="net.tcp://localhost:8086/MyService"/>
</baseAddresses>
</host>
</service>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="DefaultBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
<behavior name="ProtoBufBehavior">
<ProtoBufSerialization />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="Http.Basic.Config" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" />
<security mode="None"> …Run Code Online (Sandbox Code Playgroud) 我得到一个ProtoException("可能的递归检测到(偏移:4级):o EOW")序列化树结构时如下:
var tree = new PrefixTree();
tree.Add("racket".ToCharArray());
tree.Add("rambo".ToCharArray());
using (var stream = File.Open("test.prefix", FileMode.Create))
{
Serializer.Serialize(stream, tree);
}
Run Code Online (Sandbox Code Playgroud)
树实现:
[ProtoContract]
public class PrefixTree
{
public PrefixTree()
{
_nodes = new Dictionary<char, PrefixTree>();
}
public PrefixTree(char[] chars, PrefixTree parent)
{
if (chars == null) throw new ArgumentNullException("chars");
if (parent == null) throw new ArgumentNullException("parent");
if (chars.Length == 0) throw new ArgumentException();
_parent = parent;
_nodes = new Dictionary<char, PrefixTree>();
_value = chars[0];
var overflow = chars.SubSet(1);
if (!overflow.Any()) …Run Code Online (Sandbox Code Playgroud) 在C#中,我们在.proto中有命名空间,我们从protobuf-net获得,我们没有得到任何命名空间.所以问题是如何使用namespacs/packages生成protobuf-net生成(并使用内部).proto文件.
我们解析所有项目以生成.proto文件以将C++应用程序连接到我们的C#应用程序时的示例
enum AnimationCode {
None = 0;
Idle = 1;
//...
}
Run Code Online (Sandbox Code Playgroud)
和
enum SessionCode {
None = 0;
//...
}
Run Code Online (Sandbox Code Playgroud)
因此,当我们将该统一项目.proto文件提供给protogen编译器时,我们得到了大量的
枚举类型"SessionStateCode"没有名为"None"的值.
和
请注意,枚举值使用C++作用域规则,这意味着枚举值是其类型的兄弟,而不是它的子级.
而且没有C++代码.
要点是这样,编码的C#消息至少可以从C++中读取
有没有办法处理一个事件或回调刚刚被Protobuf反序列化的对象,而不必明确地从反序列化对象中调用该方法?
例如,假设我有以下课程:
[ProtoContract]
public class Customer
{
[ProtoMember(1)]
public string FirstName { get; set; }
[ProtoMember(2)]
public string MiddleName { get; set; }
[ProtoMember(3)]
public string LastName { get; set; }
[ProtoMember(4)]
public Dictionary<int, string> Addresses { get; set; }
public Customer()
{
//Subscibe to a Protobuf deserialization complete event?
}
public void ValidateAddresses()
{
//Some routine to validate addresses
}
}
Run Code Online (Sandbox Code Playgroud)
是否有办法调用"ValidateAddresses"而不必从反序列化的代码块中的反序列化对象中显式调用它?在构造函数中调用它是没有价值的,因为Protobuf还没有应用序列化的值,所以有一种方法可以知道它何时完成应用值.我希望有一种方法可以实现这一点,以消除在对象被使用的任何地方重构后反序列化调用的需要.
我有一些想法,但我想我会先发布这个问题,然后再向前证明这些问题,以防万一有人有一个我还没有看到的更好的(这很可能).提前致谢.
我使用Protobuf-net来序列化自定义嵌套列表.我知道原生列表不能直接嵌套,这就是我为内部列表使用容器对象的原因.但是,我还想使我的容器对象IEnumerable,但这意味着Protobuf-net将它抛出错误:
不支持嵌套或锯齿状列表和数组
以下是导致错误的列表结构示例:
[ProtoContract]
public class MyOuterList<T>
{
[ProtoMember(1)]
readonly List<MyInnerList<T>> nestedData = new List<ObjectList<T>>();
}
[ProtoContract]
public class MyInnerList<T> : IEnumerable<T>
{
[ProtoMember(1)]
private readonly List<T> data = new List<T>();
}
Run Code Online (Sandbox Code Playgroud)
修复是从IEnumerable中删除MyInnerList但显然会阻止它直接迭代.是否有[ProtobufCustomObjectSoPleaseIgnoreIEnumerable]可以使用的偷偷摸摸的属性?
到目前为止我提出的最好的替代方法是使用如下所示的Enumerable属性,但我担心该属性仍然可以再次返回到列表中.我宁愿以GetEnumerator/yield某种方式使用,但我看不出如何.
[ProtoContract]
public class MyInnerList<T>
{
[ProtoMember(1)]
private readonly List<T> data = new List<T>();
public IEnumerable<T> Data
{
get { return this.data; }
}
}
Run Code Online (Sandbox Code Playgroud) 我使用protobuf-net来序列化/反序列化我的数据.
我有一些相当简单的类,所以这不是真正的问题.
据我所知,protobuf-net使用IL生成来创建序列化/反序列化代码.虽然我的模型中只有字段,但我想知道用IL写这样一个字段怎么可能?我可以清楚地看到它运作良好,但我不知道为什么......
我试图在代码中窥探它,但它有点太复杂了.
我自己尝试生成此类代码总是会导致IL验证程序错误.
我遇到了protobuf-net的问题,我希望它是用户错误而不是protobuf-net的错误.
我可以序列化一个空集合(例如IDictionary<string, string>()),然后反序列化集合.反序列化导致非空对象(与我序列化完全一样).
但是,如果集合属于另一种类型,事情会变得很糟糕.使用非null空集合序列化自定义类型会导致集合为null的反序列化.
下面是我正在研究的内容和用于说明问题的单元测试的示例.
测试Test_Protobuf_EmptyDictionary_SerializeDeserialize通过.测试Test_Protobuf_EmptyCollectionAndPopulatedCollection_SerializeDeserialize失败.
[ProtoContract]
[ProtoInclude(100, typeof(ConcreteA))]
public abstract class AbstractClass
{
[ProtoMember(1)]
public string Name { get; set; }
[ProtoMember(2)]
public IDictionary<string, string> FieldsA { get; set; }
[ProtoMember(3)]
public IDictionary<string, string> FieldsB { get; set; }
[ProtoMember(4)]
public ICollection<string> FieldsC { get; set; }
[ProtoMember(5)]
public ICollection<string> FieldsD { get; set; }
}
[ProtoContract]
[ProtoInclude(110, typeof(ConcreteB))]
public class ConcreteA : AbstractClass
{
public ConcreteA() {}
}
[ProtoContract]
[ProtoInclude(120, typeof(ConcreteC))]
public …Run Code Online (Sandbox Code Playgroud)