简体   繁体   English

如何在svcutil.exe生成的类中更改xsd:date格式

[英]How to change xsd:date format in svcutil.exe generated classes

I generated C# classes from .wsdl file and it works. 我从.wsdl文件生成了C#类,它可以工作。 But I have following issue. 但是我有以下问题。 Service formats xsd:date types in response incorrect. 服务格式xsd:date类型在响应中不正确。 Example: 例:

<date xsi:type="xsd:date">2016-01-27 14:20:30</date>

But it should be one of these: 但这应该是其中之一:

<date xsi:type="xsd:date">2016-01-27</date>  
<date xsi:type="xsd:dateTime">2016-01-27T14:20:30</date>

And because of that I get exception 因此,我得到了例外

Unhandled Exception: System.ServiceModel.CommunicationException: Error in deserializing body of reply message for operation 'createVacature'. 未处理的异常:System.ServiceModel.CommunicationException:对操作'createVacature'的回复消息主体进行反序列化时出错。 ---> System.InvalidOperationException: There is an error in XML document (2, 646). ---> System.InvalidOperationException:XML文档(2,646)中存在错误。 ---> System.FormatException: String was not recognized as a valid DateTime. ---> System.FormatException:无法将字符串识别为有效的DateTime。

How can I override date parsing? 如何覆盖日期解析? Or any other way to fix it? 还是其他解决方法? Implementing all that manually without svcutil.exe would be overkill. 在没有svcutil.exe的情况下手动实现所有这些功能可能会过头。

Here is my solution. 这是我的解决方案。 I intercept service response before parsing and manually edit it. 我在解析之前拦截服务响应,然后手动对其进行编辑。

Here is date fixing functionality: 这是日期固定功能:

public class MessageDateFixer : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        XmlDocument document = new XmlDocument();
        MemoryStream memoryStream = new MemoryStream();
        XmlWriter xmlWriter = XmlWriter.Create(memoryStream);
        reply.WriteMessage(xmlWriter);
        xmlWriter.Flush();
        memoryStream.Position = 0;
        document.Load(memoryStream);

        FixMessage(document);

        memoryStream.SetLength(0);
        xmlWriter = XmlWriter.Create(memoryStream);
        document.WriteTo(xmlWriter);
        xmlWriter.Flush();
        memoryStream.Position = 0;
        XmlReader xmlReader = XmlReader.Create(memoryStream);
        reply = Message.CreateMessage(xmlReader, int.MaxValue, reply.Version);
    }

    private static void FixMessage(XmlDocument document)
    {
        FixAllNodes(document.ChildNodes);
    }

    private static void FixAllNodes(XmlNodeList list)
    {
        foreach (XmlNode node in list)
        {
            FixNode(node);
        }
    }

    private static void FixNode(XmlNode node)
    {
        if (node.Attributes != null &&
            node.Attributes["xsi:type"] != null)
        {
            if (node.Attributes["xsi:type"].Value == "xsd:date")
            {
                node.Attributes["xsi:type"].Value = "xsd:dateTime";
                node.InnerXml = node.InnerXml.Replace(" ", "T");
            }
        }

        FixAllNodes(node.ChildNodes);
    }
}

Here is auxiliary class: 这是辅助类:

public class DateFixerBehavior : IEndpointBehavior
{
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new MessageDateFixer());
    }

    public void Validate(ServiceEndpoint endpoint)
    {

    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {

    }
}

Here is usage: 这是用法:

PosterToolClient poster = new PosterToolClient();
poster.Endpoint.Behaviors.Add(new DateFixerBehavior());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM