WCF Serialization Information outside class definition
Suppose this simple scenario: My client has an already working .net application and he/she 开发者_StackOverflowwants to expose some functionality through WCF. So he gives me an assembly, containg a public class that exposes the followig method.
OrderDetail GetOrderDetail (int orderId) // Suppose OrderDetail has {ProductId, Quantity, Amount)
Now, I want some members of OrderDetail (Amount) not to be serialized. According to http://msdn.microsoft.com/en-us/library/aa738737.aspx, the way to do this is by means of the [DataContract] and [DataMember]/[IgnoreDataMember] attributes. However, that's not an option for me because I can not modify client's source code. So I'm looking for a way to specify which members I want to serialize out, outside the type's definition. Something that should look like this:
[OperationContract]
[IgnoreMember(typeof(OrderDetail), "Amount" )]
OrderDetail QueryOrder(int orderId){
return OrderDetail.GetOrderDetail(orderId)
}
Is there any way to to this? Thanks, Bernabé
Don't send the clients objects across the wire, create a DTO from the clients object containing only the information that you want to send and send that instead.
This allows you to control exactly what information gets sent, and is in keeping with the WCF intentions of passing messages and not objects
So create an OrderDetailDto class
and populate this with the data from the OrderDetail
returned by the call to the method in the clients code. Decorate The OrderDetailDto
with the DataContract
and DataMember
attributes (you can rename the class in here so that when it is returned by WCF it is returned with the name OrderDetail
)
Repeat this for all objects in the client code, so that at the service boundary you basically convert from DTO->Client objects and Client Objects->DTO
EDIT
Whilst there might be an option which allows what you have asked for (I am not aware of one, but hopefully someone else might be) consider that when you send use your client objects as DTOs you are using them for two purposes (the client object and the message contract), which is against the Single Responsibility Principle and when you get them on the client side they will not be the same client side objects, just DTOs with the same properties, you will not be able to get behaviour in the client side objects (at least not without sharing libraries on the server side and client side).
By binding the data contract to the objects you also end up having to manage the changes to client objects and data contracts as one thing. When they are separate you can manage the changes to client side objects without neccessarily changing the DTOs, you can just populate the differently.
Whilst it seems like it is a lot of work to create the DTOs, in the end I think it will be worth it.
You will have to write a wrapper class that only exposes the desired properties and simply calls the class your client provided to gets its values.
The only other option would be to emit a new dynamic class using reflection and serialize that (see http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.aspx), but its probably not worth the effort unless you need to build a lot of wrapper classes.
精彩评论