【问题标题】:Protobuf-net Skip data during serializationProtobuf-net 在序列化期间跳过数据
【发布时间】:2018-01-05 10:32:31
【问题描述】:

我使用代理,我想在序列化过程中执行检查以跳过错误的项目,但我找不到方法,知道吗?

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.
    }
}

【问题讨论】:

    标签: c# serialization protobuf-net


    【解决方案1】:

    您描述的不是序列化程序当前尝试定位的场景。支持条件序列化基于每个属性/字段,但不支持每个对象。

    也许仍然有办法让它工作,但这取决于上下文是什么,即在你的模型中有 Person 对象是什么?你能改变那个模型吗? (可能不是,因为您使用的是代理)。

    我的默认答案是,一旦事情停止正常工作,就是说:为您的序列化工作创建一个单独的 DTO 模型,并用您打算序列化的数据填充它 - 而不是努力让您的常规域模型很好地满足复杂的序列化要求。

    【讨论】:

    • 清除,最好在序列化过程之前对集合进行预过滤。谢谢@Marc
    • @ilCosmico 那里是你也可以用自定义集合类型做一些疯狂的事情,这些类型基本上欺骗过滤视图而不需要任何额外的存储,但是......那是 真的很乱,没有充分的理由是不能做的。如果你可以预过滤:我建议
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多