0

We have a WCF service hosted on IIS using the DataContract Serializer (Not XmlSerializer) our need is very similar to what @Surya KLSV posted "Dynamically ignore data members from getting serialized".

Based on some business rules which we would not like to go into detail, our users can choose (by configuration) to receive, or not receive certain mambers in their answers. So we use EmitDefaultValue = false, when a user does not want to receive the BirthDate member, we assign the null value and it does not appear in the response (JSON and XML).

We are facing a problem with users who chooses to receive the member BirthDate. In some cases this value is not present in our database, it is null and when we serialize the response, this member is not appearing.

What we wanted for these cases is the member to be serialized with a null value. For users who want to receive the members:

JSON:

"Someone": {
    "BirthDate": null,
    "Name": "Josua",
    "Age": null
}

XML:

<Someone>
    <BirthDate xsi: nil = "true"/>
    <Name> Josua </Name>
    <Age xsi: nil = "true"/>
</Someone>

For users who do not want to receive the member

JSON:

"Someone": {
    "Name": "Josua",
}

XML:

<Someone>
    <Name> Josua </Name>
</Someone>

For now we are solving this in an ugly way: assigning the MinDate value on that, so this member is serialized in the response, the same for member Age, we are assigning 0 (Zero).

We can not change EmitDefaultValue = true because we will break the settings on clients that do not want to receive these members, unless, this is possible to done in runtime. Which we still can not find how to do.

We have already tried the solution from Carlos's Figueira blog but without success because the framework still respects the EmitDefaultValue

Here's an exemple to ServiceContract and DataContract:

[ServiceContract]
public interface ISomeoneService
{
    [OperationContract (Name = "SearchSomeoneJson")]
    [WebInvoke (Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "SearchSomeone/json?Name={name}")
    Someone SearchSomeoneJson (string name);

    [OperationContract (Name = "SearchSomeoneXml")]
    [WebInvoke (Method = "GET", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "SearchSomeone/xml?Name={name}")
    Someone SearchSomeoneXml (string name);
}

[DataContract]
public class Someone : ISomeoneService
{
    [DataMember (EmitDefaultValue = false)]
    public DateTime? BirthDate {get; set; }

    [DataMember (EmitDefaultValue = false)]
    public string Name {get; set; }

    [DataMember (EmitDefaultValue = false)]
    public int? Age = null;
}
LeoFraietta
  • 192
  • 5
  • 13
  • DataTime object cannot be null. The default value is 1/1/01 so you can either use the default value for null, or make a string and use empty string for null. – jdweng Sep 18 '17 at 16:47
  • Thanks @jdweng we already thought about changing the type (string) but it generates modification on the users whos already using service. we are already using 1/1/01 as default, but hoping to find another solution. – LeoFraietta Sep 18 '17 at 16:56
  • You can modify the get and set properties to save value to a private property and still make it backwards compatible with existing users. – jdweng Sep 18 '17 at 17:28
  • You might be able to conditionally replace your `Someone` with a surrogate, along the lines of [Conditional WCF DataContract Serialization (Using DataContractSurrogate)](https://www.codeproject.com/Articles/417168/Conditional-WCF-DataContract-Serialization-Using). – dbc Sep 18 '17 at 18:00
  • How will the WCF client be able to distinguish between the situation where `BirthDate` is null, and `BirthDate` is not set at all? The data contract serializers don't have functionality equivalent to the [`XXXSpecified`](https://msdn.microsoft.com/en-us/library/zds0b35c.aspx) pattern for tracking whether an element is present. – dbc Sep 18 '17 at 18:15
  • DataTime object can be null if you declare property as Nullable – Iggy Zofrin Sep 18 '17 at 22:09
  • @dbc After a couple of hours of DataContract Surrogate study I cannot realize how it can help me in this specific problem. I really will appreciate some ilustrated examples. – LeoFraietta Sep 20 '17 at 14:27
  • @iggyZoFrin, I'm using nullable datetime, isn't this you suggest? "public DateTime? BirthDate {get; set; }" – LeoFraietta Sep 20 '17 at 14:31
  • 1
    @LeoFraietta - OK, I found an example of conditional serialization using surrogates from one of my old answers: [partial or full object serialization](https://stackoverflow.com/a/25456638/3744182). – dbc Sep 20 '17 at 21:13
  • @LeoFraietta - OK, after further investigation, I can't find a way within WCF to suppress the ["type hint"](https://blogs.msdn.microsoft.com/youssefm/2009/04/22/understanding-known-types/) that the data contract serializers emit when encountering a conditional replacement type. – dbc Sep 21 '17 at 05:26
  • 1
    You may need to rethink your JSON/XML format, or switch to different serializers that support the [{propertyName}Specified pattern](https://stackoverflow.com/a/37842985). That's [easy with `XmlSerializer`](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-the-xmlserializer-class) but not so easy with Json.NET [link1](https://stackoverflow.com/q/3118504), [link2](https://stackoverflow.com/q/6792785). – dbc Sep 21 '17 at 05:30
  • With sure we used another concept to bypass this problem. Tks. – LeoFraietta Jan 31 '19 at 21:46

0 Answers0