WCF 扩展一:格式化Web服务请求XML

本文介绍了一种解决Web服务中命名空间不匹配的问题的方法,通过自定义Message和客户端消息格式化器,调整WCF生成的SOAP消息的命名空间。

扩展原因

有一WebService,在工程中添加Web Service引用后调用不成功,但是用SoapUI测试正常

分析

用tctTrace跟踪报文后发现wcf生成的报文命名空间与SoapUI的不一样

解决办法

扩展WCF Message,具体如下:

 

第一步、自定义Message:

 public class MyCustomMessage : Message
 {
     private readonly Message message;
 
     public MyCustomMessage(Message message)
     {
         this.message = message;
     }
 
     public override MessageHeaders Headers
     {
         get { return this.message.Headers; }
     }
 
     public override MessageProperties Properties
     {
         get { return this.message.Properties; }
     }
 
     public override MessageVersion Version
     {
         get { return this.message.Version; }
     }
 
     protected override void OnWriteStartBody(XmlDictionaryWriter writer)
     {
         writer.WriteStartElement("soapenv", "Body", null);
     }
 
     protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
     {
         this.message.WriteBodyContents(writer);
     }
 
     protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
     {
         writer.WriteStartElement("soapenv", "Envelope", @"http://schemas.xmlsoap.org/soap/envelope/");
         writer.WriteAttributeString("xmlns", "ws", null, @"此处为自定义的命名空间");
     }
 }

第二步、自定义IClientMessageFormatter,在其中应用MyCustomMessage类

    public class MyCustomMessageFormatter : IClientMessageFormatter
    {
        IClientMessageFormatter formatter;

        public MyCustomMessageFormatter(IClientMessageFormatter formatter)
        {
            this.formatter = formatter;
        }

        public object DeserializeReply(Message message, object[] parameters)
        {
            return this.formatter.DeserializeReply(message, parameters);
        }

        public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
        {
            var message = this.formatter.SerializeRequest(messageVersion, parameters);
             return new MyCustomMessage(message);
        }
    }

第三步:实现IOperationBehavior

[AttributeUsage(AttributeTargets.Method)]
 public class MobilityProviderFormatMessageAttribute : Attribute, IOperationBehavior
 {
     public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }
 
     public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) {
         var serializerBehavior = operationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>();
 
         if (clientOperation.Formatter == null)
         {
             ((IOperationBehavior)serializerBehavior).ApplyClientBehavior(operationDescription, clientOperation);
         }
 
         IClientMessageFormatter innerDispatchFormatter = clientOperation.Formatter;
 
         clientOperation.Formatter = new MyCustomMessageFormatter(innerDispatchFormatter);
     }
 
     public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
     {
     }
 
     public void Validate(OperationDescription operationDescription) { }
 }

第四步:应用自定义Behaivor

    static void Main(string[] args)
    {
        WMS.ERPWSService2Client client = new WMS.ERPWSService2Client();

        foreach (var operation in client.ChannelFactory.Endpoint.Contract.Operations)
        {
            operation.Behaviors.Add(new MobilityProviderFormatMessageAttribute());
        }                
    }

 

参考资料:http://msdn.microsoft.com/en-us/magazine/cc163302.aspx

转载于:https://www.cnblogs.com/season2009/p/3960237.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值