本文介绍了我如何序列化DataContractSerializer的过程中替代的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个工作ChangeTrackingList实现,它做它的工作就好了,但是从客户端发送它的时候回服务器,以便它只包含了改变,我想过滤器的内容。获取的变化是容易的,因为我的名单公开了一个GetChanges方法只是这一目的。我怎样才能打断的DataContractSerializer和替代List.GetChanges(),其中列出来呢?

I have a working ChangeTrackingList implementation which does its job just fine, but I'd like to "filter" its contents when sending it from the client back to the server so that it only includes the changes. Getting the changes is easy, as my list exposes a GetChanges method for just that purpose. How can I interrupt the DataContractSerializer and substitute List.GetChanges() where List used to be?

更多细节:考虑父/子关系,其中我有一个具有多个孩子是单亲,每一个都具有一个参考回父,如客户/订单。序列化整个子列表交给客户端应用程序是很好的,因为我需要显示所有订单。我不想把所有的订单回来了到服务器时,我却救,只是更改。

More detail:Consider a parent/child relationship in which I have a single parent with multiple children, each of which has a reference back to the parent, such as Customer/Orders. Serializing the entire child list over to the client app is fine, since I need to show all the orders. I don't want to bring all the orders back over to the server when I save, however, just the changes.

难度:我已经看了实现了ISerializable,并实施自己的GetObjectData使用,这会不会很辛苦,如果不是事实,我需要preserve对象引用也是如此。如果我点了的DataContractSerializer我的图形,并启用preserveObjectReferences(通过,或者明确地通过构造函数添加行为),我会得到一个非常漂亮的图形,没有重复,但会想包括我的整个ChangeTrackingList 。如果我实现ISerializable的,我可以手动写出来我ChangeTrackingList,并且仅包括了变化,但这些子对象不会知道他们的父母引用了。

Difficulty:I have already looked at implementing ISerializable, and implementing my own GetObjectData, which wouldn't be very hard if not for the fact that I need to preserve object references as well. If I point a DataContractSerializer at my graph, and enable PreserveObjectReferences (Either by adding a behavior, or explicitly through the constructor), I'll get a very nice graph with no duplications, but it will want to include my entire ChangeTrackingList. If I implement ISerializable, I can write out my ChangeTrackingList manually, and include only the changes, but those child objects won't know their parent references anymore.

澄清:这是为了说明该问题的高度简化的例子。我不是在寻找替代的解决方案,这方面的问题。我的现实世界的问题不涉及客户,订单或订单项以任何方式。替代解决方案的客户/订单的问题是不是我要找的答案。

Clarification:This is a highly simplified example meant to illustrate the problem. I'm not looking for alternate solutions to this particular problem. My real-world problem does not involve customers, orders, or line items in any way. Alternate solutions to the Customer/Order problem are not the answers I'm looking for.

我,很简单,寻找一种方式来序列化对象图的只是有趣的部分。已经完成的机制来识别和过滤下调至有趣,我只是需要一种方法序列化过程中替代这些零件放入对象图。

I am, quite simply, looking for a way to serialize only the "interesting" parts of an object graph. The mechanism for identifying and filtering down to "interesting" is already done, I just need a way to substitute those parts into the object graph during serialization.

另外一个例子:比方说,我们有下面的电话实体的集合一个人的实体。手机是无效的没有父母,和业务规则说一个人是无效的没有至少一个电话。我不能简单地保存的人,然后将电话在两个单独的呼叫,因为每个呼叫将是一个错误。我不得不将其保存为一个单一的调用图。后来,如果我更新的人改变他们的地址,这是存储在人,并添加一个新的电话号码,以及,我需要发送更新的人,以及更改手机的列表。我不想送原装手机,因为它并没有改变。

Another Example:Let's say we have a "Person" entity with a collection of "Phone" entities below it. Phones are invalid without a parent, and the business rules say a Person is invalid without at least one phone. I cannot simply save the person, and then the phones in two separate calls, because each call would be an error. I have to save them as a graph in one single call. Later, if I update the Person to change their address, which is stored on Person, and add a new phone number as well, I need to send the updated person as well as the changes to the list of phones. I don't want to send the original phone because it hasn't changed.

这是一个人为的例子了,但多了一个非常类似于现实生活中的问题。我的父母这是无效的wihout至少一个孩子,没有孩子是有效未经父母。

It's a contrived example again, but one more closely resembles the real life problem. I have parents which are invalid wihout at least one child, and no child is valid without a parent.

更新:它看起来像替代我想执行可以由DataContractSurrogate类的方式来完成。我见过这样几个例子,它们是相对简单的,但那是因为他们的例子也是如此。他们通常是交换EmployeeSurrogate为员工的品种,其中员工是一些非序列化类的。就我而言事情变得怪异,因为我要交换类是一个泛型类型。

Update:It looks like the "substitution" I want to perform can be done by way of a DataContractSurrogate class. I've seen a few examples of this, and they are relatively straightforward, but that's because their examples are as well. They are usually of the "Swap EmployeeSurrogate for Employee" variety, where "Employee" is some non-serializable class. In my case things get weirder because the class I want to swap is a generic type.

所以,该问题的一个简单的版本可能是这个。可以说我有一个完全不可序列MYLIST类。 (而之前有人建议它,取代了MYLIST类不是一个有效的解决方案,无论是。记住乡亲,这只是一个例子。)我想建立一个DataContractSurrogate所以,每当一个MYLIST出现在我的对象图,我想转换它以一个简单数组进行序列化。

So, a simpler version of the problem might be this. Lets say I have a totally non-serializable MyList class. (And before someone suggests it, replacing the MyList class is not a valid solution, either. Remember folks, it's just an example.) I want to set up a DataContractSurrogate so that whenever a MyList appears in my object graph, I want to convert it to a simple array for serialization.

确实喜欢一个有效方向这声音给任何人?有没有人试过代孕一个泛型类型?我是疯了,即使考虑到它?

Does THIS sound like a valid direction to anyone? Has anyone ever tried to surrogate a generic type? Am I insane for even considering it?

推荐答案

好了,我终于有一些作品,并希望分享答案。不幸的是我不能简单地共享code,因为它是写在客户端的时间。

Okay, at last I have something that works, and wanted to share the answer. Unfortunately I can't simply share the code since it was written on the client's time.

的关键解决方案是DataContractSurrogate类,你可以阅读有关这里这里。通常情况下,你可以使用这个在提供一个独立的一个不可序列化类的一个对象图。

The key to the solution is the DataContractSurrogate class, which you can read about here and here. Ordinarily, you would use this to provide a stand in for an unserializable class in an object graph.

pretend用于说明的目的,我们有一个MYLIST类,它是不可序列。我们需要创建一个代理类作为它的替身。这里的命名约定是pretty的可怕,因为一个叫MyListSurrogate是真的更多的是工厂,以及一个叫MyListSurrogated是什么,我会认为是实际的替代品。无论如何,surrogated类公开的简单数组或列表,并标记为DataContract。这是类,将通过线路传输。该MyListSurrogate类实现IDataContractSurrogate,并实现了四个重要的方法。

Pretend for purposes of illustration that we have a MyList class that is not serializable. We need to create a surrogate class to act as its "stand-in". The naming conventions here are pretty horrible, since the one called MyListSurrogate is really more of a factory, and the one called MyListSurrogated is what I would consider to be the actual surrogate. Anyway, the "surrogated" class exposes a plain array or List, and is marked as a DataContract. This is the class that will go over the wire. The MyListSurrogate class implements IDataContractSurrogate, and implements four important methods.

该GetDataContractType方法返回待机中给出的实体类型类型。当给定的类型MYLIST,它应该返回MyListSurrogated。任何其他类型的应该只是回到原来​​的类型。这种方法涉及到一些乱七八糟的反映,所以我会包括$ C $下的,而不是仅仅解释它。

The GetDataContractType method returns the stand-in type given the entity type. When given the type MyList, it should return MyListSurrogated. Any other type should just return the original type. This method involves some messy reflection, and so I'll include the code for that rather than just explain it.

public Type GetDataContractType(Type type)
{
    if(type.IsGenericType 
        && (type.GetGenericTypeDefinition() == typeof(MyList<>)))
    {
        var itemType = type.GetGenericArguments()[0];
        var result = typeof(MyListSurrogated<>)
            .GetGenericTypeDefinition().MakeGenericType(itemType);
        return result;
    }
    return type;
}

在类似的方式,GetObjectToSerialize变成一个MYLIST的实例的成MyListSurrogated实例。而GetDeserializedObject变成一个MyListSurrogated实例回一个MYLIST实例。 IDataContractSurrogate包括我们将不使用其他一些方法,我刚刚返回null对于其中的大部分。

In a similar fashion, GetObjectToSerialize turns a MyList instance into a MyListSurrogated instance. And GetDeserializedObject turns a MyListSurrogated instance back into a MyList instance. IDataContractSurrogate includes several other methods that we will not be using, and I've just returned null for most of them.

在MyListSurrogate类的实例可以被传递给DataContractSerializer的构造函数,它会序列化和反序列化过程中被称为需要在飞行中替代类型。不幸的是,要通过配置指定一个代理类没有简单的方法,所以如果你没有实例化自己的DataContractSerializer,你必须实现一个DataContractSerializerOperationBehavior,你可以阅读此处。应用的操作行为是相似的方法描述这里

An instance of the MyListSurrogate class can then be passed to the DataContractSerializer constructor, and it will be called during serialization and deserialization to substitute types as needed on the fly. Unfortunately, there is no simple way to specify a surrogate class through configuration, so if you're not instantiating your own DataContractSerializer, you'll have to implement a DataContractSerializerOperationBehavior, which you can read about here. Applying the operation behavior is similar to the method described here.

要使用的代理人,你将不得不处理一些已知类型的问题。在我的例子中,MyListSurrogated类型都必须添加到已知类型你想调用服务的列表。您可以手动执行此操作,或者对于我来说是一个code生成模板的一部分。

To use surrogates, you will have to deal with some known type problems. In my example, the MyListSurrogated type would have to be added to the list of known types for the service you are trying to call. You can either do this manually, or in my case as part of a code generation template.

最后一件事。我最初的目标是创建一个ChangeTrackingList,将携旗下全部内容从服务器到客户端,但只有改变从客户端到服务器。这实际上是非常简单的,一旦代孕已被映射。我ChangeTrackingList有一个名为IncludeOriginalsWhenSerializing,默认为真布尔属性。该代理类的GetObjectToSerialize方法,着眼于该标志,以决定是否将原始项目复制到替身。就行了,在GetDeserializedObject的另一端方法再现了原ChangeTrackingList,然后设置标志设置为false反序列化过程。所以,用标志设置为true不胜枚举的一端,并出现与该标志设置为false的另一端。这很简单,这是自动的,它的完成。

One last thing. My original goal was to create a ChangeTrackingList that would carry its entire contents from server to client, but only the changes from client to server. This is actually really simple once the surrogate has been mapped. My ChangeTrackingList has a boolean property called "IncludeOriginalsWhenSerializing" that defaults to true. The surrogate class' GetObjectToSerialize method looks at this flag to decide whether or not to copy the original items into the stand-in. On the other end of the line, the GetDeserializedObject method recreates the original ChangeTrackingList, and then sets the flag to false during deserialization. So, a list with the flag set to true goes in one end, and comes out the other end with the flag set to false. It's simple, it's automatic, it's finished.

这篇关于我如何序列化DataContractSerializer的过程中替代的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 13:05