【问题标题】:How to pass a SOAP header from a client to a web service如何将 SOAP 标头从客户端传递到 Web 服务
【发布时间】:2014-12-18 16:58:49
【问题描述】:

我有一个 C# 客户端,Web 服务必须接收证书标头。我不知道如何将标头添加到 Web 服务。这是我的代码:

// Define a SOAP header by deriving from the SoapHeader base class.
// The header contains just one string value.
public class MyHeader : SoapHeader
{
    public string MyValue;
}

public partial class Service: System.Web.UI.Page
{
    MyWebService ESClient = new MyWebservice();
    private static String TAG_CERTIFICATE = "MxIFZjFCBFa...";
    protected void Page_Load(object sender, EventArgs e)
    {
        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
        CredentialCache cache = new CredentialCache();

        MyHeader header = new MyHeader();

        // Populate the values of the SOAP header.
        header.MyValue = TAG_CERTIFICATE;

        //HOW CAN I ADD THIS CERTIFICATE TO MY ESCLIENT WEB SERVICE?????

        //remSolSal is the response of the Web Service
        remSolSal response= new remSolSal();
        //remDatSol is the method of the Web Service and getRemSolEnt the parameters that I send in another function
        response = ESClient.remDatSol(getRemSolEnt());
    }

XML 模型证书:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sol="url...">
    <soapenv:Header>
        <certificate>
            JgsJSP6Ql8f........
        </certificate>

另外,我有一个 Java 客户端,它可以完成我在 C# 中必须做的事情。它使用 this 函数添加标题,其中 paramName 是“证书”,paramContent 是值“JgsJSP6Ql8f........”:

 /**
 * This method adds a custom header to message.
 * 
 * @param paramName
 */
private static void addHeaderParam(String paramName, String paramContent) {
    try {
        List<Header> headers = new ArrayList<Header>();
        Header dummyHeader = new Header(new QName(TARGETNAMESPACE,
                paramName), paramContent, new JAXBDataBinding(String.class));
        headers.add(dummyHeader);

        // client side:
        ((BindingProvider) port).getRequestContext().put(
                Header.HEADER_LIST, headers);
    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

【问题讨论】:

  • 查看getRemSolEnt()返回的对象的属性。看看它是否有标题的属性。
  • @JohnSaunders 他需要使用 WCF API 来执行此操作,它不能只分配给请求对象。
  • @moarboilerplate:如果他使用的是SoapHeader,那么他使用的是Web Reference,而不是Service Reference,所以没有WCF。
  • 没错,但似乎这只是一些测试代码,试图实现他的要求......
  • 您使用的是服务参考还是网络参考?

标签: c# xml web-services wcf soap


【解决方案1】:

有很多很多方法可以实现您的要求,这取决于您的客户端的设置方式以及您希望如何维护它。您是否使用服务参考?你想在配置或代码中管理它吗?插入自定义标头的最简单方法是在配置中的端点配置中使用 &lt;headers&gt; 元素,如下所示: http://msdn.microsoft.com/en-us/library/ms731749(v=vs.110).aspx

我个人建议不要将证书的定义放在应用程序中,而是将其存储在服务器的密钥库中。然后,您可以在应用于您的客户端的行为中引用证书。您还可以使用代码提取证书并通过引用 ESClient.ClientCredentials 对象来执行您需要的操作。

【讨论】:

    【解决方案2】:

    最后,我使用了 ClientMessageInspector 类来修改 SOAP 消息:

    public class ClientMessageInspector : System.ServiceModel.Dispatcher.IClientMessageInspector
    {
        #region IClientMessageInspector Members
    
         public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
         {
    
         }
    
         public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
         {
             CustomMessageHeader header = new CustomMessageHeader();
    
             request.Headers.Add(header);
    
             return null;
         }
    
         #endregion
     }
    
    /// <summary>
    /// Represents a custom message header.
    /// </summary>
    public class CustomMessageHeader : MessageHeader
    {
        private const string HeaderName = "CustomHeader";
        private const string HeaderNamespace = "";
    
        /// <summary>
        /// Gets the name of the message header.
        /// </summary>
        /// <returns>The name of the message header.</returns>
        public override string Name
        {
            get { return HeaderName; }
        }
    
        /// <summary>
        /// Gets the namespace of the message header.
        /// </summary>
        /// <returns>The namespace of the message header.</returns>
        public override string Namespace
        {
            get { return HeaderNamespace; }
        }
    
        /// <summary>
        /// Called when the header content is serialized using the specified XML writer.
        /// </summary>
        /// <param name="writer">
        /// An <see cref="T:System.Xml.XmlDictionaryWriter" /> that is used to serialize the header contents.
        /// </param>
        /// <param name="messageVersion">
        /// The object that contains information related to the version of SOAP associated with a message and its exchange.
        /// </param>
        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            writer.WriteElementString("certificate", "JgsJSP6Ql8f........");
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      • 1970-01-01
      • 2011-10-11
      • 2012-08-14
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多