Как я могу добавить пространство имен в мыльный конверт в C #

2

Я хочу добавить настройку пространства имен в мой конверт с мылом. Я хотел бы изменить его в BeforeSendRequest в IClientMessageInspector или у вас есть более элегантный способ.

Например

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
 <s:Header>
  <wsa:To xmlns="http://www.w3.org/2005/08/addressing">ws://xxx/V1</wsa:To>
  ...
 </s:Header>
 <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  ...
 </s:Body>
</s:Envelope>

в

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing">
...

Помогите мне, пожалуйста!

Спасибо!

Теги:
namespaces
soap
client
wcf

2 ответа

0

В соответствии с вашим описанием, я думаю, вы могли бы использовать инспектор сообщений WCF. Перед тем как клиент отправит сообщение. Мы могли бы настроить тело сообщения.
https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/message-inspectors
Я сделал демо, желаю, чтобы это было полезно для вас.
Конец сервера.

class Program
    {

        static void Main(string[] args)
        {
            Uri uri = new Uri("http://localhost:1500");
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.TransferMode = TransferMode.Buffered;
            binding.Security.Mode = BasicHttpSecurityMode.None;
            ServiceHost sh = new ServiceHost(typeof(Calculator),uri);
            sh.AddServiceEndpoint(typeof(ICalculator), binding, "");
            ServiceMetadataBehavior smb;
            smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (smb == null)
            {
                smb = new ServiceMetadataBehavior();
                //smb.HttpGetEnabled = true;
                sh.Description.Behaviors.Add(smb);
            }
            Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
            sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "MEX");


            sh.Open();
            Console.Write("Service is ready....");
            Console.ReadLine();
            sh.Close();
        }
    }
    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract,WebGet]
        double Add(double a, double b);

    }

    public class Calculator : ICalculator
    {
        public double Add(double a, double b)
        {
            return a + b;
        }

}

Клиент.

class Program
    {
        static void Main(string[] args)
        {
            ServiceReference2.CalculatorClient client = new ServiceReference2.CalculatorClient();
            try
            {
                var result = client.Add(34, 20);
                Console.WriteLine(result);
            }
            catch (Exception)
            {
                throw;
            }
        }

    }
    public class ClientMessageLogger : IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            string result = $"server reply message:\n{reply}\n";
            Console.WriteLine(result);
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {

            XmlDocument doc = new XmlDocument();
            MemoryStream ms = new MemoryStream();
            XmlWriter writer = XmlWriter.Create(ms);
            request.WriteMessage(writer);
            writer.Flush();
            ms.Position = 0;
            doc.Load(ms);

            ChangeMessage(doc);

            ms.SetLength(0);
            writer = XmlWriter.Create(ms);

            doc.WriteTo(writer);
            writer.Flush();
            ms.Position = 0;
            XmlReader reader = XmlReader.Create(ms);
            request = System.ServiceModel.Channels.Message.CreateMessage(reader, int.MaxValue, request.Version);
            string result = $"client ready to send message:\n{request}\n";
            Console.WriteLine(result);
            return null;
        }
        void ChangeMessage(XmlDocument doc)
        {
            XmlElement element = (XmlElement)doc.GetElementsByTagName("s:Envelope").Item(0);
            if (element != null)
            {
                element.SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
                element.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
            }
        }
    }
    public class CustContractBehaviorAttribute : Attribute, IContractBehavior, IContractBehaviorAttribute
    {
        public Type TargetContract => typeof(ICalculator);

        public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            return;
        }

        public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ClientMessageInspectors.Add(new ClientMessageLogger());
        }

        public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
        {
            return;
        }

        public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
        {
            return;
        }
}  

Не забудьте применить CustContractbehavior к интерфейсу сервиса.

    [CustContractBehavior]
public interface ICalculator {

Результат. Изображение 174551

  • 0
    Спасибо вам большое! это так, как мне нравится. Одно - у меня нет доступа к самой услуге. Я разрабатываю только клиента.
  • 0
    Вам нужно только применить атрибут к интерфейсу сервиса, сгенерированному путем добавления ссылок на стороне клиента. Приведенный выше код на стороне сервера просто эмулирует службу WCF, чтобы я мог сделать демонстрацию.
0

Я обычно использую XML Linq, как это

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication91
{
    class Program
    {
        static void Main(string[] args)
        {
            string ws = "http://www.w3.org/2005/08/addressing";
            string xml = string.Format( 
                         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
                         "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\">" +
                         "<s:Header>" +
                         "<wsa:Address xmlns:wsa=\"{0}\">ws://xxx/V1</wsa:Address>" +
                         "</s:Header>" +
                         "<s:Body>" +
                         "</s:Body>" +
                         "</s:Envelope>",
                         ws);
            XDocument doc = XDocument.Parse(xml);

            XElement header = doc.Descendants().Where(x => x.Name.LocalName == "Header").FirstOrDefault();
            XElement body = doc.Descendants().Where(x => x.Name.LocalName == "Body").FirstOrDefault();


        }
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню