Как изменить формат xsd:date в сгенерированных классах svcutil.exe

Я сгенерировал классы C# из файла.wsdl, и он работает. Но у меня есть следующий вопрос. Сервисные форматы xsd:date неверный тип ответа. Пример:

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

Но это должен быть один из них:

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

И из-за этого я получаю исключение

Необработанное исключение: System.ServiceModel.CommunicationException: Ошибка в десериализации тела ответного сообщения для операции 'createVacature'. ---> System.InvalidOperationException: в XML-документе произошла ошибка (2, 646). ---> System.FormatException: строка не была распознана как допустимый DateTime.

Как я могу переопределить разбор даты? Или каким-либо другим способом это исправить? Реализация всего этого вручную без svcutil.exe была бы излишней.

1 ответ

Решение

Вот мое решение. Я перехватываю ответ службы перед анализом и вручную редактирую его.

Вот функциональность фиксации даты:

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

Вот вспомогательный класс:

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

    }
}

Вот использование:

PosterToolClient poster = new PosterToolClient();
poster.Endpoint.Behaviors.Add(new DateFixerBehavior());
Другие вопросы по тегам