none
Conditional WCF DataContract Serialization RRS feed

  • Question

  • I would like to implement a conditional DataContract serialization on my WCF service, like in this codeproject example: https://www.codeproject.com/Articles/417168/Conditional-WCF-DataContract-Serialization-Using

    The goal I would like to achieve is that I can have static DataContract object on the service and when the client requests this object only some of the DataMembers are returned to the client to reduce the message size. The client could then request those sub object individually. Also the server should be able to serialize the whole DataContract including all DataMembers.

    The problem is that the codeproject example changes the actual property of the source object, so I would have to clone the whole object before sending so that my static DataContract is not changed. The best solution would be if I could create a custom DataMember attribute that would only be serialized with a custom DataContractSerializer that also looks for this attribute.

    The only solution I found so far would be to check the StackTrace inside the actual properties and check if it was called from the "Save" method on my service and only then I the property would return it's value. But I don't know if this would be a good solution for this problem.

    Is there a better way to do this?

    Tuesday, February 26, 2019 7:36 PM

All replies

  • Hi TheNetStriker,
    According to your description, I think your idea is great.  While I have some questions, are these DataMember properties useful to achieve your final goal?
    [DataMember(IsRequired = false)]
    [IgnoreDataMemeber]
    [DataMember(EmitDefaultValue = false)]

    Why do clients need to request these subclasses separately? If individual members are explicitly marked as non-required members, passing these non-required members (which can be ignored on demand) between the server and the client will not go wrong.
    Best Regards
    Abraham
    Wednesday, February 27, 2019 8:33 AM
    Moderator
  • Hi, thanks for the quick reply. The problem is that I also save this object to a file with a DataContractSerializer and there I need those conditional members to serialize also. The object I'm serving on the server has a huge hierarchical structure and it is the easiest solution to just serialize the whole object to a file to preserve the object when restarting the server. But clients only require the hierarchical structure at first and can then request the settings of each hierarchical object seperateley.

    The IsRequired property is already false by default. The IgnoreDataMember is a static way to ignore properties an could not be dynamically ignored. And the EmitDefaultValue just removes the whole node from the xml when the object is null.

    I've tried all of those options, but nothing helps me in that situation. I also found a feature request in the msdn forums that would solve my problem: https://social.msdn.microsoft.com/Forums/vstudio/en-US/1ec19929-f9e9-438b-b2f1-5deafa8ae9c3/feature-request-conditional-serialization-support-in-datamember-and-datacontractserializer?forum=wcf

    But I guess that this feature was never developed.

    Edit: What also would work is if there was a way to add properties dynamically to my File DataContractSerializer. But I also didn't find any way to do this.
    Wednesday, February 27, 2019 9:05 AM
  • Hi,

    if possible, I sugget you could submit your feature request by the following link.

    https://developercommunity.visualstudio.com/content/idea/post.html?space=61&inRegister=true

    Best Regards

    Abraham

    Tuesday, March 5, 2019 8:57 AM
    Moderator
  • I think I already found a pretty good solution for this. I'm simply checking the WCF OperationContext inside the property getter and if the MessageHeader action equals the operation I want to exclude this property from I simply return a null value. Here is an example how I check if the property was called from a service operation:

    public static bool IsMyOperation()
    {
    var currentOperationContext = OperationContext.Current;

    return currentOperationContext == null ? false 
    : currentOperationContext.IncomingMessageHeaders
    .Action.Equals("http://tempuri.org/IService/MyOperation");
    }

    Tuesday, March 5, 2019 11:39 AM