Изменить ответное сообщение WCF SOAP, чтобы добавить пространство имен и префикс к элементам - PullRequest
0 голосов
/ 12 февраля 2020

У меня есть служба WCF, которая должна общаться с устаревшим клиентом WCF, который я не могу контролировать. Он вручную анализирует ответ службы, включая префиксы пространства имен в элементе root/elm1/elm2/ns1:elm3. Ответ от службы не имеет ns1:elm3, а просто elm3, который клиент отклоняет как недействительный. Как я могу добавить его вручную перед отправкой ответа.

Я видел примеры того, как изменить ответ на сообщение SOAP с помощью метода IDispatchMessageInspector.BeforeSendReply(). Вот мое SOAP сообщение в BeforeSendReply()

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <sendMessageResponse xmlns="http://mycompany.com/service" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <sendMessageReturn>
                <deliveredTimestamp>2/10/2020 10:25:27 PM</deliveredTimestamp>
                <messageId>
                    <messageId>1581391525982</messageId>
                <messageId>
                <messageStatus>1</messageStatus>
                <messageStatusDescription>Successfully received and acknowledged</messageStatusDescription>
                <producedTimestamp>2/10/2020 10:25:10 PM</producedTimestamp>/>
            </sendMessageReturn>
        </sendMessageResponse>
    </soapenv:Body>
</soapenv:Envelope>

Клиент ожидает SOAP сообщение, подобное этому:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <sendMessageResponse xmlns="http://mycompany.com/service">
            <sendMessageReturn>
                <ns1:deliveredTimestamp xmlns:ns1="http://mycompany.com/type">2020-02-11T06:07:48.088Z</ns1:deliveredTimestamp>
                <ns2:messageId xmlns:ns2="http://mycompany.com/type">
                    <ns2:messageId>1581391525982</ns2:messageId>
                </ns2:messageId>
                <ns3:messageStatus xmlns:ns3="http://mycompany.com/type">1</ns3:messageStatus>
                <ns4:messageStatusDescription xmlns:ns4="http://mycompany.com/type">Successfully received and acknowledged</ns4:messageStatusDescription>
                <ns5:producedTimestamp xmlns:ns5="http://mycompany.com/type">2020-02-11T06:07:47.303Z</ns5:producedTimestamp>
            </sendMessageReturn>
        </sendMessageResponse>
    </soapenv:Body>
</soapenv:Envelope>

У меня это в BeforeSendReply()

MessageBuffer msgbuf = reply.CreateBufferedCopy(int.MaxValue);
System.ServiceModel.Channels.Message tmpMessage = msgbuf.CreateMessage();
XmlDictionaryReader xdr = tmpMessage.GetReaderAtBodyContents();
XElement bodyEl = XElement.Load(xdr.ReadSubtree());
var deliveredTimestamp = bodyEl.Descendants().FirstOrDefault(b => b.Name.LocalName == "deliveredTimestamp");

Я могу получить атрибут namespace, например xmlns:ns1=http://company.com/type, в deliveryTimestamp, но не могу получить префикс <ns1:deliveredTimestamp>...</ns1:deliveredTimestamp> Спасибо за вашу помощь.

Обновление:

Мне удалось создать xml с правильными префиксами пространства имен, например так:

            XElement root = new XElement(soapenv + "Envelop", new XAttribute(XNamespace.Xmlns + "soapenv", soapenv),
                            new XElement(soapenv + "Body",
                                new XElement("sendMessageResponse", new XAttribute(XNamespace.Xmlns + "i", svc),
                                    new XElement("sendMessageReturn",
                                        new XElement(type + "deliveredTimestamp", new XAttribute(XNamespace.Xmlns + "ns1", type)),
                                        new XElement(type + "messagedId", new XAttribute(XNamespace.Xmlns + "ns2", type),
                                            new XElement(type + "messageId")),
                                        new XElement(type + "messageStatus", new XAttribute(XNamespace.Xmlns + "ns3", type)),
                                        new XElement(type + "messageStatusDescription", new XAttribute(XNamespace.Xmlns + "ns4", type)),
                                        new XElement(type + "producedTimestamp", new XAttribute(XNamespace.Xmlns + "ns5", type))
                                        ))));

Теперь у меня появилась другая проблема, когда createmessage () изменяет <soapenv:Envelope на <s:Envelope и клиенту это не нравится.

                var newMessage = System.ServiceModel.Channels.Message.CreateMessage(reply.Version, null, xr);

                newMessage.Headers.CopyHeadersFrom(reply);
                newMessage.Properties.CopyProperties(reply.Properties);

                reply = newMessage;

Кстати, код выше является копией другого SO сообщения кем-то.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...