-1

well I am trying to develop a soap client, it wanted its custom soapheader(i.e.usercred) to serialized, but after doing so I get this as error System.Runtime.Serialization.InvalidDataContractException: 'Type 'ConsoleApp1.Program+usercred' cannot inherit from a type that is not marked with DataContractAttribute or SerializableAttribute. Consider marking the base type System.Web.Services.Protocols.SoapHeader with DataContractAttribute or SerializableAttribute, or removing them from the derived type.'

it kinda wants soapheader to be also serialized plz help

1 Answers1

0

There are several ways to add custom soup header in your soup request.

For example you can create soup request using HTTPRequest where you can build soup envelope as you want. 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)
    {

    }

If you are consuming WCF service then you can add custom behavior in your request. 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;
    }
}

Test Client should be like

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

You can also try WebService Headers Authentication

  • my custom soap header is added, by another method but it requires all the data members to be serialized....which cant be done as its base class is System.Web.Services.Protocols.SoapHeader – Paul Thomas Jun 27 '19 at 08:07