更改WCF 4.0 REST服务中的json日期时间序列化

更改WCF 4.0 REST服务中的json日期时间序列化,json,wcf,rest,Json,Wcf,Rest,我需要在WCF REST自托管服务中替换JSON的日期时间序列化。现在,我正在使用下面的代码来实现它,但这肯定不是一种方法,因为它需要操作每个类 [DataContract] public class Test { [IgnoreDataMember] public DateTime StartDate; [DataMember(Name = "StartDate")] public string StartDateStr { get {

我需要在WCF REST自托管服务中替换JSON的日期时间序列化。现在,我正在使用下面的代码来实现它,但这肯定不是一种方法,因为它需要操作每个类

[DataContract]
public class Test
{
    [IgnoreDataMember]
    public DateTime StartDate;

    [DataMember(Name = "StartDate")]
    public string StartDateStr
    {
        get { return DateUtil.DateToStr(StartDate); }
        set { StartDate = DateTime.Parse(value); }
    }
}
其中,我的实用程序函数DateUtil.DateToStr执行所有格式化工作

有没有什么简单的方法可以做到这一点,而不必接触我的类中具有DataContract属性的属性?理想情况下,在我的配置中没有属性,但有几行代码可以将序列化程序替换为覆盖了日期时间序列化的序列化程序

我发现的所有东西看起来都需要更换巨大的管道

本文似乎不适用,因为在中,我使用的是WebServiceHost而不是HttpServiceHost,它不是4.5.1框架的一部分


JSON中有一个转换日期时间的限制,特别是根据您的情况

请看 并阅读日期/时间和JSON部分


为了解决这个问题,我简单地将所有调用的序列化类型从
JSON
更改为
XML
,包括
DateTime

,经过长时间的讨论,我找到了解决方案。 请使用以下代码来解决序列化日期

[IgnoreDataMember]
public DateTime? PerformanceDate { get; set; }

[DataMember(EmitDefaultValue = false, Name = "PerformanceDate")]
public string UpdateStartDateStr
{
    get
    {
        if (this.PerformanceDate.HasValue)
            return this.PerformanceDate.Value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture);
        else
            return null;
    }
    set
    {
        // should implement this...
    }
}

默认情况下,WCF使用DataContractJsonSerializer将数据序列化为JSON。不幸的是,这个序列化程序中的数据格式很难被人脑解析

"DateTime": "\/Date(1535481994306+0200)\/"
要覆盖此行为,我们需要编写自定义IDispatchMessageFormatter。这个类将接收所有应该返回给请求者的数据,并根据我们的需要进行更改

要使其发生在端点中的操作,请添加自定义格式化程序-ClientJsonDateFormatter

ServiceHost host=new ServiceHost(typeof(CustomService));
host.AddServiceEndpoint(typeof(ICustomContract), new WebHttpBinding(), Consts.WebHttpAddress);

foreach (var endpoint in host.Description.Endpoints)
{
    if (endpoint.Address.Uri.Scheme.StartsWith("http"))
    {
        foreach (var operation in endpoint.Contract.Operations)
        {
            operation.OperationBehaviors.Add(new ClientJsonDateFormatter());
        }
        endpoint.Behaviors.Add(new WebHttpBehavior());
     }
 }
ClientJsonDateFormatter是一个简单的类,它只应用formatterClientJsonDateFormatter

public class ClientJsonDateFormatter : IOperationBehavior
{
    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) {  }

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { }

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        dispatchOperation.Formatter = new ResponseJsonFormatter(operationDescription);
    }

    public void Validate(OperationDescription operationDescription) { }
}
在格式化程序中,我们接受输入并使用更改的序列化程序对其进行序列化:

public class ResponseJsonFormatter : IDispatchMessageFormatter
{
    OperationDescription Operation;
    public ResponseJsonFormatter(OperationDescription operation)
    {
        this.Operation = operation;
    }

    public void DeserializeRequest(Message message, object[] parameters)
    {
    }

    public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
    {
        string json=Newtonsoft.Json.JsonConvert.SerializeObject(result);
        byte[] bytes = Encoding.UTF8.GetBytes(json);
        Message replyMessage = Message.CreateMessage(messageVersion, Operation.Messages[1].Action, new RawDataWriter(bytes));
        replyMessage.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Raw));
        return replyMessage;
    }
}
要向客户发送信息,我们需要数据编写器-RawDataWriter。它的实现很简单:

class RawDataWriter : BodyWriter
{
    byte[] data;
    public RawDataWriter(byte[] data)
        : base(true)
    {
        this.data = data;
    }

    protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
    {
        writer.WriteStartElement("Binary");
        writer.WriteBase64(data, 0, data.Length);
        writer.WriteEndElement();
    }
}
应用所有代码将以更友好的格式返回日期:

"DateTime":"2018-08-28T20:56:48.6411976+02:00"
为了在实践中展示它,我在分支DateTimeFormatter中创建了一个示例


请检查并回答,因为您可能也需要它。

我查看了WCF json序列化程序的参考源,它有一个名为DateTimeFormat的属性,但我不知道如何更改它。我也在MSDN论坛上发布过,但似乎没有人知道如何访问它。你链接到的文章没有说不可能,也没有说有限制。它只是讨论默认使用的格式。@b似乎有一个限制。我忘记了看到限制详细信息的确切链接,但是您尝试过XML吗?它可以很好地处理XML。还可以看到数据是如何在JSON中序列化的,比如/DATE(700234020+3000)/@bpeikes请通过以下两个链接:我们已经有大量的代码在客户端使用JSON。我在服务器上使用了我的工作。所以我们可以继续使用它。你发的两篇文章我都看过了。他们都没有提到DataContractJsonSerializer是WCF的一部分,它有一个名为DateTimeFormat的成员。下载WCF的参考源,你会看到它就在那里。你的解决方案正是我在问题中提出的。我的服务有96个日期时间。我应该坐下来改变96次吗?如果我错过了一个,或者我忘了在将来应用这个模式呢。更集中的方式会更好。