在发送请求之前需要在 WCF 客户端中操作 SOAP 标头方面获得帮助

发布于 2024-11-30 07:27:28 字数 9912 浏览 0 评论 0原文

我有一个独特的要求,我需要在请求中向外部供应商发送高度定制的肥皂标头。我的 WCF 客户端与其 Web 服务交互的唯一方法是使用用户名令牌和对整个信封进行消息签名的组合(请参阅下面供应商提供的肥皂头)。

   <soapenv:Envelope xmlns:bsvc="urn:com.workday/bsvc"   xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
   <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
  <wsse:UsernameToken wsu:Id="UsernameToken-20" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:Username>Cert509User</wsse:Username>
  </wsse:UsernameToken>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
        <DigestValue>Lx8YS/gC/oTagK0cn2rzGCQcYSSiZC9CKqIFqd/X8zw=</DigestValue>
      </Reference>
    </SignedInfo>
      <SignatureValue>p9Z1inN//gcDH85KFfd3RB6jY9hEy93ZqSj1l+sGakpvTgyivTbD0mDXKMpEwQVxCqtsEP9r78voxjlAbgM5PJyMQsmIxz+KQ45LyaA8dDdA4X4TIJ89dgvacT5PY0rtxJD2u2T5cRvQJ7p9etJL4FcQMI9I6XyU7DcKFOuRehE=</SignatureValue>
    <KeyInfo>
      <X509Data>
        <X509Certificate>MIIDuzCCAqOgAwIBAgIQK2RKs3P21+p4XAV83a/QLjANBgkqhkiG9w0BAQUFADCBrjETMBEGCgmSJomT8ixkARkWA2NvbTEaMBgGCgmSJomT8ixkARkWCm1hc3RlcmNhcmQxHTAbBgNVBAoTFE1hc3RlckNhcmQgV29ybGRXaWRlMSQwIgYDVQQLExtHbG9iYWwgSW5mb3JtYXRpb24gU2VjdXJpdHkxNjA0BgNVBAMTLUlURiBNQyBQcm9kdWN0aW9uIE5ldHdvcmsgQXBwbGljYXRpb25zIHN1YiBDQTAeFw0xMTA4MDQwOTQwNDlaFw0xNTA4MDMwOTA2NDRaMIGoMQswCQYDVQQGEwJVUzERMA8GA1UECBMITWlzc291cmkxFDASBgNVBAcTC1NhaW50IExvdWlzMTQwMgYDVQQKEytNYXN0ZXJDYXJkIFdvcmxkV2lkZSAtIENvbW1vbiBQcm9kSW5mcmEgU1NMMREwDwYDVQQLEwhzaWduaW5nMTEnMCUGA1UEAxMec3RhZ2Uud29ya2RheUhSLm1hc3RlcmNhcmQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCt4MlJCVNcmXiQIg8pxR4JsR0QpIuBCPadIAo849CRLpZglIKRWrTlxRIBC2YQeW3OkuDEdqYU6wJzn9m6GHTbmOSAy21aVR0eOqQLHltXytdzOJG92HW1IlBVuzwmMKwzEUjhVatLRQjKvTs6TjJ7egfzO8H2yolU59fq/zLcpQIDAQABo10wWzAfBgNVHSMEGDAWgBQCt+lVDTcnQt+zKa7QBi4/hEiVUzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4EFgQUM23TyPCInFlw2PnukzGOn8kKldcwDQYJKoZIhvcNAQEFBQADggEBAJeAcKk3YWN12frCQSuKzO4qTBNo+QjUjXEHfYuUl8i2pJHs6tDuDkX36RYPWyXLyMPXHSOoomlVmsCprGLqfTGBf1jW/e7Re3sg3/k1iJFg3f1mMKxGP0MuUvuofc/Nj+ezvvl/Nswn3bsAMgvktM+OR5KEhi293qlix87mpvmuvDUw1ZfoQpgN8AvdiQiRWBN2SXahwzGJo+gRjy6EUGdNgc+lsPDkkKxF6csWsb59yip4t7nTbSjqi5XCjZYfMAG5cDhDELtqge5i1W+1a0mP12xKb5P205HSjH9jF/N67CwOBxuuUXaexsqbLaRfL0Dxo0oFwusnIQ1A2qMgg1c=</X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
SOAP BODY goes HERE
</soapenv:Body>
</soapenv:Envelope>

我尝试过将 wshttpbinding、自定义绑定与“app.config”中的不同行为结合起来。我无法复制上面显示的 SOAP 标头,也无法连接到 Web 服务。这只是需要设置标头的方式,我无法通过 app.config 进行配置。因此,我向供应商询问如何在 WCF 客户端中复制标头。他们向我发送了一段代码(x509 Authentication.cs),他们对其进行了测试并确认其有效(不知道它如何为他们工作)。基本上,当我的 WCF 客户端将请求发送给供应商时,我“以某种方式”需要拦截请求,拦截后以某种方式将 SOAP 主体作为方法的输入传递(CreateX509SoapEnvelope(“SOAP body”))。我已附上完整的代码下面的 x509 Authentication.cs

    class x509_Authentication
     {
      public string CreateX509SoapEnvelope(string xml)
      {
        string soapXML;
        soapXML = "<soapenv:Envelope xmlns:bsvc=\"urn:com.workday/bsvc\" 
                   xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">";
        soapXML += "<soapenv:Header>\n";

        // Add security block for X.509 certificate
        soapXML = "<wsse:Security xmlns:wsse=\"http://docs.oasis-
                   open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">";
        soapXML += "<wsse:UsernameToken wsu:Id=\"UsernameToken-20\"     
                    xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-
                     wss-wssecurity-utility-1.0.xsd\">";
        soapXML += "<wsse:Username>Cert509User</wsse:Username>";
        soapXML += "</wsse:UsernameToken>";
        soapXML += "</wsse:Security>";

        soapXML += "</soapenv:Header>" + xml + "</soapenv:Envelope>";

        // Sign Envelope
        soapXML = CreateSignatureBlock(soapXML, "wsse:Security");

        // Verify that the XML was signed properly
        VerifySignedXml(soapXML);

        return soapXML;
    }

    public string CreateSignatureBlock(string xml, string sParentSignatureTagName)
    {
        try
        {
            string certificatePath="C:\\Users\\user3434\\Desktop\\certfolder\\cert.p12";
            //load xml into a dom
            XmlDocument xd = new XmlDocument();
            xd.LoadXml(xml);

            // Set Certificate
            System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new X509Certificate2(certificatePath, "changeit");
            //System.Security.Cryptography.X509Certificates.X509Certificate2 cert = x509_Authentication.GetCertificateFromStore();
            SignedXml signedXml = new SignedXml(xd);
            signedXml.SigningKey = cert.PrivateKey;

            // Create a new KeyInfo object.
            KeyInfo keyInfo = new KeyInfo();
            keyInfo.Id = "";

            // Load the certificate into a KeyInfoX509Data object
            // and add it to the KeyInfo object.
            KeyInfoX509Data keyInfoData = new KeyInfoX509Data();
            keyInfoData.AddCertificate(cert);
            keyInfo.AddClause(keyInfoData);

            // Add the KeyInfo object to the SignedXml object.
            signedXml.KeyInfo = keyInfo;

            // Need to use External Canonicalization method.
            signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";

            // Create a reference to be signed.
            Reference reference = new Reference();
            reference.Uri = "";

            // Add an enveloped transformation to the reference.
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
            reference.AddTransform(env);
            reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";

            // Add the reference to the SignedXml object.
            signedXml.AddReference(reference);

            // Add the Signature Id
            signedXml.Signature.Id = "";

            // Compute the signature.
            signedXml.ComputeSignature();

            // Get the XML representation of the signature and save
            // it to an XmlElement object.
            XmlElement xmlDigitalSignature = signedXml.GetXml();

            // Append the Signature element to the XML document. It will find the element after which we want to insert the signature
            XmlNodeList nodeList = xd.GetElementsByTagName(sParentSignatureTagName);
            if (nodeList.Count > 0)
            {
                XmlNode headerNode = nodeList[0];
                headerNode.AppendChild(xd.ImportNode(xmlDigitalSignature, true));
            }

            return xd.InnerXml;
        }
        catch
        {
            return xml;
        }
    }

    public void VerifySignedXml(String xml)
    {

        // Create a new XML document.
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.PreserveWhitespace = true;
        xmlDocument.LoadXml(xml);

        // Create a new SignedXml object and pass it
        // the XML document class.
        SignedXml signedXml = new SignedXml(xmlDocument);

        // Add an enveloped transformation to the reference.
        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

        Reference reference = new Reference();
        reference.AddTransform(env);
        signedXml.AddReference(reference);

        // Find the "Signature" node and create a new XmlNodeList object.
        XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");

        // Load the signature node.
        signedXml.LoadXml((XmlElement)nodeList[0]);

        // Check the signature and return the result.
        //if (!signedXml.CheckSignature(cert,true))
        //if (!signedXml.CheckSignature(new X509Certificate2(certificatePath, "sdfdf"), true))
        //{
        //    log.Error("Invalid Signature");
        //}
    }

}

}

代码接受肥皂体 &将自定义标头缝合在一起,并将整个信封返回标头签名为字符串。我需要获取该字符串并将其传递回请求并将其发送给供应商。从理论上讲,这对我来说听起来太复杂了。但通过研究,我发现有一种方法可以通过实现 IClientMessageInspector 接口并重写“BeforeSendRequest”方法来捕获传出消息。我得到了代码的一部分,当执行 WCF 客户端时,将调用“BeforeSendRequest”方法。但现在我陷入了如何从传出消息中提取 SOAP 正文(我在调试时看到正文)并将其作为 Createx509Envelope 方法的输入发送,然后获取该方法的输出并将其放回“ request”对象并将消息发送给供应商..请参阅我的 BeforeSendRequest 方法实现(其中没有太多内容,我被困住了)

    public string RequestMessage { get; set; }
        public string ResponseMessage { get; set; }


  object IClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
        {

            **HOW TO EXTRACT SOAPBODY FROM “.ServiceModel.Channels.Message request” OBJECT and CONVERT THAT TO STRING ??????????**

x509_Authentication x509 = new x509_Authentication();
            this.ResponseMessage = x509.CreateX509SoapEnvelope(SOAP Body);

**TAKE THE RESPONSE MESSAGE AND CONVERT BACK TO “.ServiceModel.Channels.Message request” AND SEND THE REQUEST ALONG???????????**

            return null;
        }

是否有更好的实现方法?请提供示例..这是我第一次必须向供应商发送自定义 SOAP 标头,这对我来说很复杂。时间紧迫。请帮忙!!!!!!

I have a unique requirement where I need to send a highly customized soap header in a request to a external vendor. The only way my WCF client can interact with their web service is using a combination of Username token and message signing the entire envelope(see vendor provided soap header below).

   <soapenv:Envelope xmlns:bsvc="urn:com.workday/bsvc"   xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
   <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
  <wsse:UsernameToken wsu:Id="UsernameToken-20" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:Username>Cert509User</wsse:Username>
  </wsse:UsernameToken>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
        <DigestValue>Lx8YS/gC/oTagK0cn2rzGCQcYSSiZC9CKqIFqd/X8zw=</DigestValue>
      </Reference>
    </SignedInfo>
      <SignatureValue>p9Z1inN//gcDH85KFfd3RB6jY9hEy93ZqSj1l+sGakpvTgyivTbD0mDXKMpEwQVxCqtsEP9r78voxjlAbgM5PJyMQsmIxz+KQ45LyaA8dDdA4X4TIJ89dgvacT5PY0rtxJD2u2T5cRvQJ7p9etJL4FcQMI9I6XyU7DcKFOuRehE=</SignatureValue>
    <KeyInfo>
      <X509Data>
        <X509Certificate>MIIDuzCCAqOgAwIBAgIQK2RKs3P21+p4XAV83a/QLjANBgkqhkiG9w0BAQUFADCBrjETMBEGCgmSJomT8ixkARkWA2NvbTEaMBgGCgmSJomT8ixkARkWCm1hc3RlcmNhcmQxHTAbBgNVBAoTFE1hc3RlckNhcmQgV29ybGRXaWRlMSQwIgYDVQQLExtHbG9iYWwgSW5mb3JtYXRpb24gU2VjdXJpdHkxNjA0BgNVBAMTLUlURiBNQyBQcm9kdWN0aW9uIE5ldHdvcmsgQXBwbGljYXRpb25zIHN1YiBDQTAeFw0xMTA4MDQwOTQwNDlaFw0xNTA4MDMwOTA2NDRaMIGoMQswCQYDVQQGEwJVUzERMA8GA1UECBMITWlzc291cmkxFDASBgNVBAcTC1NhaW50IExvdWlzMTQwMgYDVQQKEytNYXN0ZXJDYXJkIFdvcmxkV2lkZSAtIENvbW1vbiBQcm9kSW5mcmEgU1NMMREwDwYDVQQLEwhzaWduaW5nMTEnMCUGA1UEAxMec3RhZ2Uud29ya2RheUhSLm1hc3RlcmNhcmQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCt4MlJCVNcmXiQIg8pxR4JsR0QpIuBCPadIAo849CRLpZglIKRWrTlxRIBC2YQeW3OkuDEdqYU6wJzn9m6GHTbmOSAy21aVR0eOqQLHltXytdzOJG92HW1IlBVuzwmMKwzEUjhVatLRQjKvTs6TjJ7egfzO8H2yolU59fq/zLcpQIDAQABo10wWzAfBgNVHSMEGDAWgBQCt+lVDTcnQt+zKa7QBi4/hEiVUzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4EFgQUM23TyPCInFlw2PnukzGOn8kKldcwDQYJKoZIhvcNAQEFBQADggEBAJeAcKk3YWN12frCQSuKzO4qTBNo+QjUjXEHfYuUl8i2pJHs6tDuDkX36RYPWyXLyMPXHSOoomlVmsCprGLqfTGBf1jW/e7Re3sg3/k1iJFg3f1mMKxGP0MuUvuofc/Nj+ezvvl/Nswn3bsAMgvktM+OR5KEhi293qlix87mpvmuvDUw1ZfoQpgN8AvdiQiRWBN2SXahwzGJo+gRjy6EUGdNgc+lsPDkkKxF6csWsb59yip4t7nTbSjqi5XCjZYfMAG5cDhDELtqge5i1W+1a0mP12xKb5P205HSjH9jF/N67CwOBxuuUXaexsqbLaRfL0Dxo0oFwusnIQ1A2qMgg1c=</X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
SOAP BODY goes HERE
</soapenv:Body>
</soapenv:Envelope>

I have tried combination of wshttpbinding, custom binding with different behaviors in “app.config”. I was unable to replicate the SOAP header shown above nor was I able connect to web service. It is just the way the header needs to be setup that I cannot configure thru app.config. So I asked my vendor on how I can replicate the header within the WCF client. They sent me a block of code(x509 Authentication.cs) that they tested and confirmed that it works(no idea how it worked for them). Basically I “somehow” need to intercept the request as my WCF client sends the request to the vendor , after intercepting it somehow pass the SOAP body as an input to a method ( CreateX509SoapEnvelope(“SOAP body”)).I have Attached complete code x509 Authentication.cs below

    class x509_Authentication
     {
      public string CreateX509SoapEnvelope(string xml)
      {
        string soapXML;
        soapXML = "<soapenv:Envelope xmlns:bsvc=\"urn:com.workday/bsvc\" 
                   xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">";
        soapXML += "<soapenv:Header>\n";

        // Add security block for X.509 certificate
        soapXML = "<wsse:Security xmlns:wsse=\"http://docs.oasis-
                   open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">";
        soapXML += "<wsse:UsernameToken wsu:Id=\"UsernameToken-20\"     
                    xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-
                     wss-wssecurity-utility-1.0.xsd\">";
        soapXML += "<wsse:Username>Cert509User</wsse:Username>";
        soapXML += "</wsse:UsernameToken>";
        soapXML += "</wsse:Security>";

        soapXML += "</soapenv:Header>" + xml + "</soapenv:Envelope>";

        // Sign Envelope
        soapXML = CreateSignatureBlock(soapXML, "wsse:Security");

        // Verify that the XML was signed properly
        VerifySignedXml(soapXML);

        return soapXML;
    }

    public string CreateSignatureBlock(string xml, string sParentSignatureTagName)
    {
        try
        {
            string certificatePath="C:\\Users\\user3434\\Desktop\\certfolder\\cert.p12";
            //load xml into a dom
            XmlDocument xd = new XmlDocument();
            xd.LoadXml(xml);

            // Set Certificate
            System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new X509Certificate2(certificatePath, "changeit");
            //System.Security.Cryptography.X509Certificates.X509Certificate2 cert = x509_Authentication.GetCertificateFromStore();
            SignedXml signedXml = new SignedXml(xd);
            signedXml.SigningKey = cert.PrivateKey;

            // Create a new KeyInfo object.
            KeyInfo keyInfo = new KeyInfo();
            keyInfo.Id = "";

            // Load the certificate into a KeyInfoX509Data object
            // and add it to the KeyInfo object.
            KeyInfoX509Data keyInfoData = new KeyInfoX509Data();
            keyInfoData.AddCertificate(cert);
            keyInfo.AddClause(keyInfoData);

            // Add the KeyInfo object to the SignedXml object.
            signedXml.KeyInfo = keyInfo;

            // Need to use External Canonicalization method.
            signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";

            // Create a reference to be signed.
            Reference reference = new Reference();
            reference.Uri = "";

            // Add an enveloped transformation to the reference.
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
            reference.AddTransform(env);
            reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";

            // Add the reference to the SignedXml object.
            signedXml.AddReference(reference);

            // Add the Signature Id
            signedXml.Signature.Id = "";

            // Compute the signature.
            signedXml.ComputeSignature();

            // Get the XML representation of the signature and save
            // it to an XmlElement object.
            XmlElement xmlDigitalSignature = signedXml.GetXml();

            // Append the Signature element to the XML document. It will find the element after which we want to insert the signature
            XmlNodeList nodeList = xd.GetElementsByTagName(sParentSignatureTagName);
            if (nodeList.Count > 0)
            {
                XmlNode headerNode = nodeList[0];
                headerNode.AppendChild(xd.ImportNode(xmlDigitalSignature, true));
            }

            return xd.InnerXml;
        }
        catch
        {
            return xml;
        }
    }

    public void VerifySignedXml(String xml)
    {

        // Create a new XML document.
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.PreserveWhitespace = true;
        xmlDocument.LoadXml(xml);

        // Create a new SignedXml object and pass it
        // the XML document class.
        SignedXml signedXml = new SignedXml(xmlDocument);

        // Add an enveloped transformation to the reference.
        XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

        Reference reference = new Reference();
        reference.AddTransform(env);
        signedXml.AddReference(reference);

        // Find the "Signature" node and create a new XmlNodeList object.
        XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");

        // Load the signature node.
        signedXml.LoadXml((XmlElement)nodeList[0]);

        // Check the signature and return the result.
        //if (!signedXml.CheckSignature(cert,true))
        //if (!signedXml.CheckSignature(new X509Certificate2(certificatePath, "sdfdf"), true))
        //{
        //    log.Error("Invalid Signature");
        //}
    }

}

}

The code accepts soap body & stitches together the custom header and signs the entire envelope returning header as a string. I need to take this string and pass it back to the request and send it on its way to the vendor. It sounds way too complicated for me theoritically. But with research I found that there was a way to trap the outgoing message by implementing the IClientMessageInspector interface and overriding the “BeforeSendRequest” method. I got the part of the code working where when WCF client is executed the “BeforeSendRequest” method is being called. But now I am stuck at how to extract the SOAP body from the outgoing message (I see the body when I debug) and send it to as an input to Createx509Envelope method and then take the output of the method and put it back in the “request” object and send the message to the vendor .. see my BeforeSendRequest method implementation(nothing much in there I am stuck)

    public string RequestMessage { get; set; }
        public string ResponseMessage { get; set; }


  object IClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
        {

            **HOW TO EXTRACT SOAPBODY FROM “.ServiceModel.Channels.Message request” OBJECT and CONVERT THAT TO STRING ??????????**

x509_Authentication x509 = new x509_Authentication();
            this.ResponseMessage = x509.CreateX509SoapEnvelope(SOAP Body);

**TAKE THE RESPONSE MESSAGE AND CONVERT BACK TO “.ServiceModel.Channels.Message request” AND SEND THE REQUEST ALONG???????????**

            return null;
        }

If there is better way of implementing it ? please provide samples.. this is the first where I had to send a custom SOAP header to vendor and its complicated for me. Running short on time. PLEASE HELP!!!!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

森林很绿却致人迷途 2024-12-07 07:27:28

请查看以下文章,其中向您展示了如何实现 IClientMessageInspector 的示例,该 IClientMessageInspector 会更改消息并注入自定义标头。

处理自定义 SOAP通过 WCF 行为的标头

首先,您需要定义一个自定义标头来表示 SOAP 标头的内容。为此,请创建您自己的 MessageHeader 类。

public class MyHeader : MessageHeader
{ 
    //... 
}

创建一个注入自定义标头的 IClientMessageInspector 实现就在发送请求之前 (BeforeSendRequest)。

public class CustomMessageInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
        request = buffer.CreateMessage();
        request.Headers.Add(new MyHeader());
        return null;
    }

    //...
}

现在您需要将自定义消息检查器添加到 WCF 管道,但您已经涵盖了这一部分。

BeforeSendRequest(参考消息请求,IClientChannel 通道)的 Message 参数可用于使用 消息类型 (ToString(), GetBody(), GetReaderAtBodyContents()...等) 。

要获取消息正文,请使用 GetReaderAtBodyContents() 方法,该方法返回 XmlDictionaryReader 对象。使用此 XML 读取器以字符串形式检索正文。

例如:

using (XmlDictionaryReader reader = message.GetReaderAtBodyContents())
{
    string content = reader.ReadOuterXml();
    //...   
}

Check out the following article which shows you an example of how to implement an IClientMessageInspector which alters the message and injects a custom header.

Handling custom SOAP headers via WCF Behaviors

First you need to define a custom header to represent the contents of a SOAP header. To do so create your own descendant of the MessageHeader class.

public class MyHeader : MessageHeader
{ 
    //... 
}

Create an IClientMessageInspector implementation that injects your custom header just before sending the request (BeforeSendRequest).

public class CustomMessageInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
        request = buffer.CreateMessage();
        request.Headers.Add(new MyHeader());
        return null;
    }

    //...
}

Now you need to add your custom message inspector to the WCF pipeline, but you already got this part covered.

The Message parameter of the BeforeSendRequest(ref Message request, IClientChannel channel) can be used to read the SOAP message using one of the methods of the Message type (ToString(), GetBody(), GetReaderAtBodyContents()...etc.).

To get the body of the message use the GetReaderAtBodyContents() method which returns an XmlDictionaryReader object. Use this XML reader to retrieve the body as a string.

For example:

using (XmlDictionaryReader reader = message.GetReaderAtBodyContents())
{
    string content = reader.ReadOuterXml();
    //...   
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文