Soapheader无法序列化

时间:2019-06-27 06:31:05

标签: c# asp.net soap-client

好吧,我正在尝试开发一个肥皂客户端,它希望将其自定义的soapheader(即usercred)序列化,但是这样做之后,我得到了这个错误 System.Runtime.Serialization.InvalidDataContractException:'Type'ConsoleApp1.Program + usercred'无法从未标记DataContractAttribute或SerializableAttribute的类型继承。考虑使用DataContractAttribute或SerializableAttribute标记基本类型System.Web.Services.Protocols.SoapHeader,或将它们从派生类型中删除。'

有点希望soapheader也可以序列化plz帮助

1 个答案:

答案 0 :(得分:0)

有几种方法可以在汤请求中添加自定义汤头。

例如,您可以使用HTTPRequest创建汤请求,您可以在其中构建汤信封。 Client to send SOAP request and receive response

        public override string Process(string UserName,string Password)
    {
        string uri = "https://serviceURL";

        HttpWebRequest req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(uri));
        req.ContentType = "application/soap+xml; charset=utf-8";            
        req.Method = "POST";
        string soapRequest = BuildSoapRequest(UserName,Password);
        StreamWriter stm = new StreamWriter(req.GetRequestStream(), Encoding.UTF8);
        stm.Write(soapRequest);
        stm.Close();

        try
        {
            HttpWebResponse wr = (HttpWebResponse)req.GetResponse();
            StreamReader srd = new StreamReader(wr.GetResponseStream());

            string response = srd.ReadToEnd();
            return ExtractResponse(response);
        }
        catch (WebException e)
        {
            string error = "";
            HttpWebResponse errRsp = (HttpWebResponse)e.Response;
            if (errRsp != null)
            {
                using (StreamReader rdr = new StreamReader(errRsp.GetResponseStream()))
                {
                    string line;
                    while ((line = rdr.ReadLine()) != null)
                    {
                        error += line;
                    }
                }
            }
            throw new Exception(e.Message + "<br/> " + error);
        }
        catch (Exception e)
        {
            throw e;
        }
    }
    private string BuildSoapRequest(string UserName,string Password)
    {
        StringBuilder soapRequest = new StringBuilder();

        soapRequest.Append("<soap:Envelope xmlns:cor=\"http://www.caqh.org/SOAP/WSDL/CORERule2.2.0.xsd\" xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:tem=\"http://tempuri.org/\">");
        soapRequest.Append("<soap:Header>");
        soapRequest.Append("<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">");
        soapRequest.Append("<wsse:UsernameToken>");
        soapRequest.Append("<wsse:Username>" + UserName + "</wsse:Username>");
        soapRequest.Append("<wsse:Password>" + Password + "</wsse:Password>");
        soapRequest.Append("</wsse:UsernameToken>");
        soapRequest.Append("</wsse:Security>");
        soapRequest.Append("</soap:Header>");
        soapRequest.Append("<soap:Body>");
        soapRequest.Append("</soap:Body>");
        soapRequest.Append("</soap:Envelope>");

        return soapRequest.ToString();
    }

     private static string ExtractResponse(string soap)
    {

    }

如果您正在使用WCF服务,则可以在请求中添加自定义行为。 Custom Endpoint Behavior not being used in WCF Client with Service Reference

public class CustomClientBehavior : IEndpointBehavior
{
    string _username;
    string _password;
    public CustomClientBehavior(string username, string password)
    {
        _username = username;
        _password = password;
    }
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {

    }
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        CustomInspector inspector = new CustomInspector(_username, _password);
        clientRuntime.MessageInspectors.Add(inspector);
    }
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {

    }
    public void Validate(ServiceEndpoint endpoint)
    {

    }
}

public class CustomClientBehaviorExtensionElement : BehaviorExtensionElement
{
    string _username;
    string _password;

    public CustomClientBehaviorExtensionElement(string username, string password)
    {
        _username = username;
        _password = password;
    }

    public override Type BehaviorType
    {
        get { return typeof(CustomClientBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new CustomClientBehavior(_username, _password);
    }
}

public class CustomInspector : IClientMessageInspector
{
    string _username;
    string _password;

    public CustomInspector(string username, string password)
    {
        _username = username;
        _password = password;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        return;
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        request.Headers.Clear();
        string headerText = "<wsse:UsernameToken xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">" +
                                "<wsse:Username>{0}</wsse:Username>" +
                                "<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">" +
                                "{1}</wsse:Password>" +
                            "</wsse:UsernameToken>";
        headerText = string.Format(headerText, _username, _password);
        XmlDocument MyDoc = new XmlDocument();
        MyDoc.LoadXml(headerText);
        XmlElement myElement = MyDoc.DocumentElement;
        System.ServiceModel.Channels.MessageHeader myHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", myElement, false);
        request.Headers.Add(myHeader);
        return Convert.DBNull;
    }
}

测试客户端应类似于

TestService.Client objClient = new TestService.Client();
objClient.Endpoint.Behaviors.Add(new CustomClientBehavior(UserName, Password));

您也可以尝试WebService Headers Authentication