2017-04-11 25 views
0

我有一套工作的WCF Web服務,編碼爲.NET 4.6 - 它們正在向服務器發出呼叫。所以,他們運行在一個.EXE(實際上最終將作爲Windows服務運行)。WCF尋址 - 刪除WSA:TO元素

這些Web服務需要支持WS-Addressing的標準:

W3C Web服務尋址1.0 - 核心http://www.w3.org/TR/2006/REC-ws-addr-core-20060509

該版本的標準規定了WSA的:TO元素是可選的。我需要的是WSA:TO元素根本不出現在SOAP輸出中。我想這樣做,而不必編寫自定義SOAP編寫器,因爲我也需要使用WS-SECURITY。我GOOGLE等等等等

在我綁定的配置我有:

<binding name="MyServiceThatMustNotSendWSATO"> 
     <textMessageEncoding messageVersion="Soap12WSAddressing10" /> 
     <httpTransport /> 
    </binding> 

隨着終點:

<endpoint address="http://destinationserver.com/SomeServiceName/V1" 
    behaviorConfiguration="cliBeh" binding="customBinding" bindingConfiguration="MyServiceThatMustNotSendWSATO" 
    contract="SomeContract.SomeMethod" name="SomeEndPointName"> 
    <identity> 
     <dns value="somedns" /> 
    </identity> 
    </endpoint> 

我已經試過可用textMessageEncoding messageVersion的所有組合,但WSA:TO元素仍然生成:(

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> 
    <s:Header> 
     <a:Action s:mustUnderstand="1">tns:ServiceEntryStatusOut_V1</a:Action> 
     <a:MessageID>urn:uuid:88eda3c6-2b6a-4672-8e96-28f0e91c8b4c</a:MessageID> 
     <a:RelatesTo>urn:uuid:1f19a9f3-6e46-47cc-b190-cc7ef71dbc67</a:RelatesTo> 
     <a:To s:mustUnderstand="1">http://www.com/</a:To> 
    </s:Header> 

所以在堅果殼中,我需要W S-Address字段,例如Action,Message ID,RelatesTo,但不是To元素。

回答

0

你曾經有過項目嗎?那麼,這個問題是我面臨的一些夢魘問題的一部分。但最終,我克服了所有困難,並得到了一個可行的解決方案。這不是一個好的解決方案,但它永遠不會如此。

無論如何簡而言之,要解決這個特定的問題,我不得不使用自定義ClientMessageInspector類來刪除違規字段。該類然後是自定義行爲擴展的一部分。在我的問題中,我說我不想這樣做 - 在我的研究中,這根本不可能。您確實需要自定義類來覆蓋默認的.NET SOAP處理類。

我的自定義代碼檢查結束如下:

internal class ClientMessageInspector : IEndpointBehavior, IClientMessageInspector 
{ 
    public void Validate(ServiceEndpoint endpoint) 
    { 
    } 

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
    { 
    } 

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
    { 
     //throw new Exception("Exception in ApplyDispatchBehavior : "); 
    } 

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
    { 
     //throw new Exception("Exception in ApplyClientBehavior : "); 
     clientRuntime.ClientMessageInspectors.Add(this); 
    } 

    public object BeforeSendRequest(ref Message request, IClientChannel channel) 
    { 
     //throw new Exception("Exception in BeforeSendRequest : " + request.Headers.MessageId); 
     var message = request; 
     request = new MyCustomMessage(message); 
     return null; 
    } 

    public class MyCustomMessage : Message 
    { 
     private readonly Message _message; 

     public MyCustomMessage(Message message) 
     { 
      this._message = message; 
     } 

     protected override void OnWriteBodyContents(System.Xml.XmlDictionaryWriter writer) 
     { 
      MethodInfo dynMethod = _message.GetType().GetMethod("OnWriteBodyContents", BindingFlags.NonPublic | BindingFlags.Instance); 
      dynMethod.Invoke(_message, new object[] { writer }); 
     } 

     public override MessageHeaders Headers 
     { 
      get 
      { 
       // Remove wsa:To header 
       var index = this._message.Headers.FindHeader("To", "http://www.w3.org/2005/08/addressing"); 
       if (index > 0) 
       { 
        this._message.Headers.RemoveAt(index); 
       } 

       // Remove wsa:ReplyTo header 
       index = this._message.Headers.FindHeader("ReplyTo", "http://www.w3.org/2005/08/addressing"); 
       if (index > 0) 
       { 
        this._message.Headers.RemoveAt(index); 
       } 

       // Remove VsDebuggerCausalityData (only appears in Dev but here from convenience) 
       index = this._message.Headers.FindHeader("VsDebuggerCausalityData", "http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink"); 
       if (index > 0) 
       { 
        this._message.Headers.RemoveAt(index); 
       } 

       return this._message.Headers; 
      } 
     } 

     public override MessageProperties Properties 
     { 
      get { return this._message.Properties; } 
     } 

     public override MessageVersion Version 
     { 
      get { return this._message.Version; } 
     } 

    } 

    public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 
     //throw new Exception("Exception in AfterReceiveReply : "); 
    } 
} 

的結合所必需的複雜,但最終如下。關鍵是要使用自定義行爲擴展來完成繁重的工作以刪除這些字段。

<system.serviceModel> 

    <extensions> 

     <behaviorExtensions> 
     <add name="myBehaviorExtensionElement" 
      type="MySecurityBE.MyBehaviorExtensionElement, MySecurityBE, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> 
     </behaviorExtensions> 

    </extensions> 

    <bindings> 

     <customBinding> 

     <binding name="ServiceName_soap12" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" 
     sendTimeout="00:01:00" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" 
     maxReceivedMessageSize="65536" useDefaultWebProxy="true" allowCookies="false"> 
      <textMessageEncoding messageVersion="Soap12WSAddressing10" /> 
      <httpTransport maxReceivedMessageSize="2147483647" /> 
     </binding> 

     </customBinding> 

    </bindings> 

    <behaviors> 

     <endpointBehaviors> 
     <behavior name="cliBeh"> 
      <myBehaviorExtensionElement/> 
      <clientCredentials> 
      <clientCertificate storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName" findValue="BradTestClientKey"/> 
      <serviceCertificate> 
       <defaultCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="localhost2"/> 
       <authentication certificateValidationMode="None" trustedStoreLocation="LocalMachine"/> 
      </serviceCertificate> 
      </clientCredentials> 
     </behavior> 
     </endpointBehaviors> 

    </behaviors> 

    <client> 

     <endpoint address="http://localhost.fiddler/TestRigClient_WS/Services/MyService" 
       binding="customBinding" bindingConfiguration="ServiceName_soap12" 
       contract="GenericFileTransferService.GenericFileTransfer" 
       name="ServiceName_soap12" behaviorConfiguration="cliBeh"> 
     <identity> 
      <dns value="localhost2"/> 
     </identity> 
     </endpoint> 


    </client> 

    <diagnostics> 
     <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false" maxMessagesToLog="30000000" maxSizeOfMessageToLog="2000000"/> 
    </diagnostics> 

    </system.serviceModel> 

我希望任何人都面臨同樣的戰鬥好運。萬歲的REST和SOAP可能會死掉一個非常安靜的死亡,這真是太值得了(在我花費在這個項目上的噩夢之後,我的意見就是這樣)。