Protobuf-net 在序列化期间跳过数据
Protobuf-net Skip data during serialization
我使用代理项,我想执行检查以在序列化过程中跳过错误的项目,但我找不到方法,知道吗?
BeforeSerialize 方法在创建代理后调用,我想知道如何跳过在 protoBuf 序列化上下文中没有指定要求的项目。
下面是重现我的场景的示例代码。
public class Person
{
public Person(string name, GenderType gender)
{
Name = name;
Gender = gender;
}
public string Name { get; set; }
public GenderType Gender { get; set; }
}
public class PersonSurrogate
{
public string Name { get; set; }
public byte Gender { get; set; }
public PersonSurrogate(string name, byte gender)
{
Name = name;
Gender = gender;
}
protected virtual bool CheckSurrogateData(GenderType gender)
{
return gender == GenderType.Both || (GenderType)Gender == gender;
}
#region Static Methods
public static implicit operator Person(PersonSurrogate surrogate)
{
if (surrogate == null) return null;
return new Person(surrogate.Name, (GenderType)surrogate.Gender);
}
public static implicit operator PersonSurrogate(Person source)
{
return source == null ? null : new PersonSurrogate(source.Name, (byte)source.Gender);
}
#endregion
protected virtual void BeforeSerialize(ProtoBuf.SerializationContext serializationContext)
{
var serializer = serializationContext.Context as FamilySerializer;
if (serializer == null)
throw new ArgumentException("Serialization context does not contain a valid Serializer object.");
if (!CheckSurrogateData(serializer.GenderToInclude))
{
// ** How can I exclude this item from the serialization ? **//
}
}
}
[Flags]
public enum GenderType : byte
{
Male = 1,
Female = 2,
Both = Male | Female
}
/// <summary>
/// Class with model for protobuf serialization
/// </summary>
public class FamilySerializer
{
public GenderType GenderToInclude;
public RuntimeTypeModel Model { get; protected set; }
protected virtual void FillModel()
{
Model = RuntimeTypeModel.Create();
Model.Add(typeof(Family), false)
.SetSurrogate(typeof(FamilySurrogate));
Model[typeof(FamilySurrogate)]
.Add(1, "People") // This is a list of Person of course
.UseConstructor = false;
Model.Add(typeof(Person), false)
.SetSurrogate(typeof(PersonSurrogate));
MetaType mt = Model[typeof(PersonSurrogate)]
.Add(1, "Name")
.Add(2, "Gender");
mt.SetCallbacks("BeforeSerialize", null, null, null); // I'd like to check surrogate data and skip some items - how can I do?
mt.UseConstructor = false; // Avoids to use the parameterless constructor.
}
}
您所描述的不是序列化程序当前尝试定位的场景。 per-property/field 支持条件序列化,但不支持每个对象。
尽管如此,可能仍然有办法让它发挥作用 - 但这取决于上下文是什么,即 有什么 一个 Person
对象在你的模型中?你能改变那个模型吗? (可能不是,因为您使用的是代理人)。
我的默认答案是,一旦事情完全停止工作,就是说:为您的序列化工作创建一个单独的 DTO 模型,并用您打算序列化的数据填充该模型 - 而不是努力让您的常规域模型很好地满足复杂的序列化要求。
我使用代理项,我想执行检查以在序列化过程中跳过错误的项目,但我找不到方法,知道吗?
BeforeSerialize 方法在创建代理后调用,我想知道如何跳过在 protoBuf 序列化上下文中没有指定要求的项目。
下面是重现我的场景的示例代码。
public class Person
{
public Person(string name, GenderType gender)
{
Name = name;
Gender = gender;
}
public string Name { get; set; }
public GenderType Gender { get; set; }
}
public class PersonSurrogate
{
public string Name { get; set; }
public byte Gender { get; set; }
public PersonSurrogate(string name, byte gender)
{
Name = name;
Gender = gender;
}
protected virtual bool CheckSurrogateData(GenderType gender)
{
return gender == GenderType.Both || (GenderType)Gender == gender;
}
#region Static Methods
public static implicit operator Person(PersonSurrogate surrogate)
{
if (surrogate == null) return null;
return new Person(surrogate.Name, (GenderType)surrogate.Gender);
}
public static implicit operator PersonSurrogate(Person source)
{
return source == null ? null : new PersonSurrogate(source.Name, (byte)source.Gender);
}
#endregion
protected virtual void BeforeSerialize(ProtoBuf.SerializationContext serializationContext)
{
var serializer = serializationContext.Context as FamilySerializer;
if (serializer == null)
throw new ArgumentException("Serialization context does not contain a valid Serializer object.");
if (!CheckSurrogateData(serializer.GenderToInclude))
{
// ** How can I exclude this item from the serialization ? **//
}
}
}
[Flags]
public enum GenderType : byte
{
Male = 1,
Female = 2,
Both = Male | Female
}
/// <summary>
/// Class with model for protobuf serialization
/// </summary>
public class FamilySerializer
{
public GenderType GenderToInclude;
public RuntimeTypeModel Model { get; protected set; }
protected virtual void FillModel()
{
Model = RuntimeTypeModel.Create();
Model.Add(typeof(Family), false)
.SetSurrogate(typeof(FamilySurrogate));
Model[typeof(FamilySurrogate)]
.Add(1, "People") // This is a list of Person of course
.UseConstructor = false;
Model.Add(typeof(Person), false)
.SetSurrogate(typeof(PersonSurrogate));
MetaType mt = Model[typeof(PersonSurrogate)]
.Add(1, "Name")
.Add(2, "Gender");
mt.SetCallbacks("BeforeSerialize", null, null, null); // I'd like to check surrogate data and skip some items - how can I do?
mt.UseConstructor = false; // Avoids to use the parameterless constructor.
}
}
您所描述的不是序列化程序当前尝试定位的场景。 per-property/field 支持条件序列化,但不支持每个对象。
尽管如此,可能仍然有办法让它发挥作用 - 但这取决于上下文是什么,即 有什么 一个 Person
对象在你的模型中?你能改变那个模型吗? (可能不是,因为您使用的是代理人)。
我的默认答案是,一旦事情完全停止工作,就是说:为您的序列化工作创建一个单独的 DTO 模型,并用您打算序列化的数据填充该模型 - 而不是努力让您的常规域模型很好地满足复杂的序列化要求。