在WCF 4.0 REST Service中更改JSON DateTime序列化 [英] Change the json DateTime serialization in WCF 4.0 REST Service

查看:73
本文介绍了在WCF 4.0 REST Service中更改JSON DateTime序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在WCF REST自托管服务中替换JSON的DateTime序列化.现在,我正在使用类似以下代码的方法来执行此操作,但这绝对不是可行的方法,因为它需要处理每个类.

I need to replace the DateTime serialization for JSON in WCF REST Self Hosted service. Right now, I'm using something like the following code to do it, but it's definitely not the way to go since it requires manipulating each class.

[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完成所有格式化工作.

where my utility function DateUtil.DateToStr does all the formatting work.

是否有任何简便的方法可以实现,而无需触碰具有DataContract属性的类上的属性?理想情况下,将没有属性,但是在我的配置中需要几行代码,以用我覆盖了DateTime序列化的代码替换序列化器.

Is there any easy way to do it without having to touch the attributes on my classes which have the DataContract attribute? Ideally, there would be no attributes, but a couple of lines of code in my configuration to replace the serializer with one where I've overridden DateTime serialization.

我发现的所有内容似乎都必须替换大量的管道.

Everything that I've found looks like I have to replace huge pieces of the pipeline.

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

This article doesn't appear to apply because in I'm using WebServiceHost not HttpServiceHost, which not part of the 4.5.1 Framework.

用于WCF REST服务的JSON.NET序列化器

推荐答案

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

By default WCF uses DataContractJsonSerializer to serialize data into JSON. Unfortunatelly date from this serializer is in very difficult format to parse by human brain.

"DateTime": "\/Date(1535481994306+0200)\/"

要覆盖此行为,我们需要编写自定义IDispatchMessageFormatter.此类将接收所有应返回给请求者的数据,并根据我们的需求进行更改.

To override this behavior we need to write custom IDispatchMessageFormatter. This class will receive all data which should be returned to requester and change it according to our needs.

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

To make it happen to the operations in the endpoint add custom formatter - 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 是简单的类,仅应用格式化程序 ClientJsonDateFormatter

ClientJsonDateFormatter is simple class which just applies formatter ClientJsonDateFormatter

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) { }
}

在格式化程序中,我们获取了imput并使用更改后的Serializer对其进行了序列化:

In the formatter we took imput and serialize it with the changed Serializer:

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 .它的实现很简单:

And to send information to client we need data writer - RawDataWriter. Its implementation is simple:

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();
    }
}

应用所有代码将以更友好的格式返回日期:

Applying all code will result in returning date in more friendly format:

"DateTime":"2018-08-28T20:56:48.6411976+02:00"

为了在实践中展示它,我在 github 中创建了示例分支 DateTimeFormatter .

To show it in practice I created example in the github branch DateTimeFormatter.

也请检查答案非常可能您也将需要它.

Please check also this answer as very likely you also will need it.

这篇关于在WCF 4.0 REST Service中更改JSON DateTime序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆