如何在WCF服务上序列化可为空的DateTime

时间:2015-05-06 17:11:47

标签: c# asp.net xml wcf

我在 DataContract 中有一个带有可空日期时间成员的WCF服务,如下所示。由于业务规则,此 datamember 无法将 EmitDefaultValue 设置为 true ,且类型必须为“ DateTime?” 。

[DataContract(Name = "DADOS")]
public class Dados 
{
    [DataMember(EmitDefaultValue = false, Name = "NASCIMENTO")]
    public DateTime? DtNascimento = null;
}

我的服务合同如下所示,看到我必须有两个版本的Webinvoke方法来保持不同的系统互操作性(Json和XML响应):

[ServiceContract]
public interface IRestService
{
    [OperationContract(Name = "ConsultaDadosXml")]
    [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "ConsultaDados/xml?token={token}")]
    Dados ConsultaDadosXml(string token);

    [OperationContract(Name = "ConsultaDadosJson")]
    [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "ConsultaDados/json?token={token}")]
    Dados ConsultaDadosJson(string token);
}

问题是,当 DtNascimento 值从数据库中获得一个好的值时,一切正常。当数据库中的此值真的是 null 时,XML / JSON响应没有NASCIMENTO标记,这是因为我们有 EmitDefaultValue = false 。我可以设置我的数据库在发生这种情况时向我发送一个空值,但我的序列化对象在响应中带有一个MinDate值。

Xml版本:

<DADOS>
    <NASCIMENTO>1900-01-01T00:00:00</NASCIMENTO>
</DADOS>

Json版本:

{
    "NASCIMENTO": "/Date(-2208981600000-0200)/",
}

我真正需要的是当该值为null时在答案上显示的空变量,因为Web服务上插入了其他系统试图解释这些值,因此最好的解决方案是保留空变量:

Xml版本:

<DADOS>
    <NASCIMENTO></NASCIMENTO>
</DADOS>

Json版本:

{
    "NASCIMENTO": "",
}

任何建议都将受到赞赏。

韩国社交协会

莱奥

1 个答案:

答案 0 :(得分:1)

您可以创建一个代理字符串值私有属性,该属性返回null DateTime?值的空字符串,并对其进行序列化。它以下列格式生成一个空元素:

<NASCIMENTO></NASCIMENTO>

XML standard定义,与<NASCIMENTO />具有相同的含义。

[DataContract(Name = "DADOS")]
public class Dados
{
    [IgnoreDataMember]
    public DateTime? DtNascimento { get; set; }

    [DataMember(EmitDefaultValue = false, Name = "NASCIMENTO")]
    string DtNascimentoString
    {
        get
        {
            if (DtNascimento == null)
                return string.Empty;
            return XmlConvert.ToString(DtNascimento.Value, XmlDateTimeSerializationMode.RoundtripKind);
        }
        set
        {
            if (string.IsNullOrEmpty(value))
                DtNascimento = null;
            else
                DtNascimento = XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.RoundtripKind);
        }
    }
}