首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WCF寻址-删除WSA:TO元素

WCF寻址-删除WSA:TO元素
EN

Stack Overflow用户
提问于 2017-04-11 04:21:00
回答 1查看 1.4K关注 0票数 1

我使用.NET 4.6编写了一组工作web服务--它们正在向服务器发出出站呼叫。因此,它们在.EXE中运行(实际上最终将以Windows的形式运行)。

这些web服务需要支持WS-寻址标准:

W3C网络服务寻址1.0 -核心http://www.w3.org/TR/2006/REC-ws-addr-core-20060509

该标准版本声明WSA:TO元素是可选的。我需要的是WSA:TO元素根本不出现在SOAP输出中。我想这样做,而不必编写自定义的SOAP编写器,因为我还需要使用WS-安全性。我搜索过等等。

在绑定配置中,我有:

代码语言:javascript
复制
    <binding name="MyServiceThatMustNotSendWSATO">
      <textMessageEncoding messageVersion="Soap12WSAddressing10" />
      <httpTransport />
    </binding>

终点为:

代码语言:javascript
复制
  <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元素:(

代码语言:javascript
复制
<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>

因此,在坚果外壳中,我需要WS-Address字段,比如Action、Message、RelatesTo,而不是To元素。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-05 01:13:03

你有过这样的项目吗?嗯,这个问题是我面临的一些噩梦问题的一部分。但最后,我战胜了他们,找到了解决办法。这不是一个很好的解决方案,但它永远不会是这样的。

总之,为了解决这个特殊问题,我不得不使用自定义的ClientMessageInspector类来删除违规字段。然后,该类是自定义行为扩展的一部分。在我的问题中,我说我不想这样做--在我的研究中,这是不可能的。您确实需要自定义类来覆盖默认的.NET SOAP处理类。

我的自定义检查器代码最终得到如下结果:

代码语言:javascript
复制
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 : ");
    }
}

所需的绑定非常复杂,但最终结果如下。关键是使用自定义行为扩展来做繁重的工作来移除这些字段。

代码语言:javascript
复制
  <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>

我祝愿所有面临同样战斗的人好运。祝你长命百岁,安息,愿肥皂死得好好安静,这是我应得的(我在那个项目上度过的噩梦之年之后,我的看法)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43336712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档