Protobuf-net root序列化完整性

时间:2014-06-11 12:00:14

标签: json entity-framework asp.net-web-api protobuf-net integrity

我有两个相互引用的物体。

    [JsonObject(IsReference = true)]
    [DataContract(IsReference = true, Namespace = "http://schemas.datacontract.org/2004/07/TrackableEntities.Models")]
    [ProtoContract]
    public class ProtoBufObject : ITrackable
    {
        [DataMember(Order = 3)]
        public Guid Oid { get; set; }
        [DataMember(Order = 4)]
        [ProtoMember(4, AsReference = true)]
        public ChildProtoBufObject child { get; set; }
        [DataMember(Order = 1)]
        public TrackingState TrackingState { get; set; }
        [DataMember(Order = 2)]
        public ICollection<string> ModifiedProperties { get; set; }
    }

    [JsonObject(IsReference = true)]
    [DataContract(IsReference = true, Namespace = "http://schemas.datacontract.org/2004/07/TrackableEntities.Models")]
    [ProtoContract]
    public class ChildProtoBufObject : ITrackable
    {

        [DataMember(Order = 3)]
        public Guid Oid { get; set; }

        [DataMember(Order = 4)]
        [ProtoMember(4, AsReference = true)]
        public ProtoBufObject parent { get; set; }

        [DataMember(Order = 1)]
        public TrackingState TrackingState { get; set; }
        [DataMember(Order = 2)]
        public ICollection<string> ModifiedProperties { get; set; }
    }

在客户端上,我实例化这些对象并制作&#34; association&#34;。

 ProtoBufObject parent = new ProtoBufObject()
         {
             Oid = Guid.NewGuid()
         };
         ChildProtoBufObject child = new ChildProtoBufObject()
         {
             Oid = Guid.NewGuid()
         };
         parent.child = child;
         child.parent = parent;

对象将按如下方式序列化:

    ProtoBufFormatter formatter = new ProtoBufFormatter();
    HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, requestUri);
    requestMessage.Content = new ObjectContent<SearchParameters>(searchParameters, formatter);

而且它们将通过http发送到Webapi,在那里它将被反序列化 在WebApiContrib.Formatting.ProtoBuf。

的帮助下

在Webapi控制器中,我接收到具有正确关系的对象,但关系的完整性出错了。我用Json将对象转储到一个文件中:

 string json = JsonConvert.SerializeObject(samples);
            //write string to file
            string oid = samples.First().Oid.ToString();
            System.IO.File.WriteAllText(@"D:\JsonTest\dummypath" + oid + ".txt", json);

以下是此文本文件的内容

[{
    "$id": "1",
    "TrackingState": 0,
    "ModifiedProperties": null,
    "Oid": "8c00ea73-ac84-4130-b1a8-61e1df89f9bf",
    "child": {
        "$id": "2",
        "TrackingState": 0,
        "ModifiedProperties": null,
        "Oid": "81026a01-7de2-4045-ac0a-314b3fd7360c",
        "parent": {
            "$id": "3",
            "TrackingState": 0,
            "ModifiedProperties": null,
            "Oid": "8c00ea73-ac84-4130-b1a8-61e1df89f9bf",
            "child": {
                "$ref": "2"
            }
        }
    }
}]
孩子有一个新的&#34; id = 3而不是ref = 1的父级。 id = 3父级具有对孩子的正确引用。

所以它接缝顶级对象将无法正确设置。这是实体框架的一个大问题(这就是我提出这个问题的原因)因为它使用了类型的引用,而不仅仅是属性(这是正确的)。

我也尝试使用ProtoContract(DefaultRefencetype = true),但这使它更加糟糕。然后我收到id = 3的父母,一个id = 4的新孩子。

我的问题是:如何使对象的完整性发挥作用?

我想要的是:

[{
    "$id": "1",
    "TrackingState": 0,
    "ModifiedProperties": null,
    "Oid": "8c00ea73-ac84-4130-b1a8-61e1df89f9bf",
    "child": {
        "$id": "2",
        "TrackingState": 0,
        "ModifiedProperties": null,
        "Oid": "81026a01-7de2-4045-ac0a-314b3fd7360c",
        "parent": {
            "$ref": "1"
            }
        }
    }
}]

编辑: 实体框架行

dbContext.Set<ProtoBufObject>.AddRange(myObjects);

抛出InvalidOperationException,因为模型(parent,child.parent)的完整性不同。

Additional information: Conflicting changes to the role 'foo_bar_Target' of the relationship 'Entities.Context.foo_bar' have been detected.

如果我在客户端使用Newtonsoft.Json序列化程序并通过WebApi发送它(我使用与我的Protobuf测试具有相同关系的相同对象),Entity Framework可以处理这些对象。因此,Json和Protobuf的反序列化对象之间必定存在一些差异。这就是为什么我再次序列化对象以查看差异的原因。

我还在Put方法中添加了参考检查:

if (protoBufObject != protoBufObject.child.parent)
{
    throw new Exception("Instance integrity differs!");
}

从json文件中预期会抛出此异常,因此引用确实已损坏。

在WebApi的启动中,我使用以下代码:

        config.Formatters.Add(new ProtoBufFormatter());

有问题吗?我是否需要向格式化程序添加更多信息?

0 个答案:

没有答案