Answered Calling WCF WEB SERVICE from RAW Socket Client written in C#

  • Monday, June 09, 2008 11:45 PM
     
     

     

    have a simple WCF Web service with BasicHttpBinding that I want to call a method from by using the following client

    public void TestSoapUsingSocket()
        {
          Socket s = null;
         
          try
          {
            int port = 4790;

            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPEndPoint ep = new IPEndPoint(Dns.GetHostEntry("127.0.0.1").AddressList[0], port);

            s.Connect(ep);

            StringBuilder builder = new StringBuilder();
            builder.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            builder.Append("<soap:Envelope xmlnsTongue Tiedoap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"             xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
            builder.Append("<soap:Body>");
            builder.Append("<Test xmlns=\"http://somenamespace.com\" />");
            builder.Append("</soap:Body>");
            builder.Append("</soap:Envelope>");

            StringBuilder sb = new System.Text.StringBuilder();
            sb.Append("POST /SomeService.svc HTTP/1.1\r\n");
            sb.Append("Host: HOSTNAME.COM\r\n");
            sb.Append("Content-Type: text/xml; charset=utf-8\r\n");
            sb.AppendFormat("Content-Length: {0}\r\n",
              System.Text.Encoding.UTF8.GetBytes(builder.ToString()).Length);
            sb.Append("SOAPAction: \"http://localhost:4970/SomeService.svc/Test\"\r\n");
            sb.Append("\r\n");
            sb.Append(builder.ToString());

            byte[] send = System.Text.Encoding.UTF8.GetBytes(sb.ToString());

            System.Text.StringBuilder resp = new System.Text.StringBuilder();
            int ct = 0;
            byte[] receive = new byte[4096];
            while ((ct = s.Receive(receive)) > 0)
            {
              resp.Append(System.Text.Encoding.UTF8.GetString(receive));
              receive = new byte[4096];
            }
          }
          catch (Exception exc)
          {
            string str = exc.ToString();
          }
          finally
          {
            s.Close();
          }
        }

    I am getting the following response which mainly is a bad request

    HTTP/1.1 400 Bad Request
    Server: ASP.NET Development Server/9.0.0.0
    Date: Mon, 09 Jun 2008 23:32:00 GMT
    Content-Length: 1208
    Connection: Close

    <html>
        <head>
            <title>Bad Request</title>
            <style>
                  body {font-family:"Verdana";font-weight:normal;font-size: 8pt;color:black;}
                  p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
                  b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
                  h1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
                  h2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
                  pre {font-family:"Lucida Console";font-size: 8pt}
                  .marker {font-weight: bold; color: black;text-decoration: none;}
                  .version {color: gray;}
                  .error {margin-bottom: 10px;}
                  .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
            </style>
        </head>
        <body bgcolor="white">

                <span><h1>Server Error in '/' Application.<hr width=100% size=1 color=silver></h1>

                <h2> <i>HTTP Error 400 - Bad Request.</i> </h2></span>

                <hr width=100% size=1 color=silver>

                <b>Version Information:</b>&nbsp;ASP.NET Development Server 9.0.0.0

                </font>

        </body>
    </html>

    When I invoke the service using a client that is generated using SVCUTIL.EXE it works ok.

    I would higly higly appreciate if some one could help me out.

    Thanks in advance

All Replies

  • Tuesday, June 10, 2008 7:06 AM
    Moderator
     
     
    Hi rizwan,

     Why do you want to do this in the first place? It seems like a terrible idea.

     If you are using at least .NET 2.0 you can always create an ASMX-style proxy client (Since you are using the BasicHttpBinding).

    If you have some strange reason of ignoring all the standard methods of doing this; at least use the System.Net.WebClient to do this for you.

     Good luck,

      --larsw
  • Tuesday, June 10, 2008 1:13 PM
     
     Answered

    The WCF service is not "liking" the request you're sending. If you add tracing (http://msdn2.microsoft.com/en-us/library/ms733025.aspx) to the service you'll know exactly what the problem is with the request.

     

    Since you said that callng the service using a svcutil-generated client works, you can "peek" at the request sent by this client to format the socket-based request. There is more information about it at http://blogs.msdn.com/carlosfigueira/archive/2008/01/13/writing-custom-requests-to-simple-wcf-services.aspx.

  • Tuesday, June 10, 2008 2:43 PM
     
     

     

    Lars:

     

    I know it is a terrible idea. I am doing just to make sure that I can call a WCF service by sending a SOAP message over HTTP/1.1. I have used System.Net.Webclient too but got similar results.

  • Tuesday, June 10, 2008 3:25 PM
     
     
    Carlos:
    I guess what I need is to figure out what consitute a correct SOAP 1.1 request. 
    The ASMX web service (.NET framework 2.0) would generate SOAP 1.1/SOAP 1.2 
    and HTTP POST request when you would query for wsdl. Below is such a request from an 
    ASMX service (ASP.NET Web service). I have emulated the same exact thing in my test 
    code but that does not work.
    POST /CalendarService.asmx HTTP/1.1
    Host: localhost
    Content-Type: text/xml; charset=utf-8
    Content-Length: length
    SOAPAction: "http://tempuri.org/TestMethod"
    
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlnsTongue Tiedoapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://tempuri.org/" xmlns:types="http://tempuri.org/encodedTypes" xmlnsTongue Tiedoap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <tns:TestMethod xsi:type="tns:TestMethod">
          <name xsi:type="xsdTongue Tiedtring">string</name>
        </tns:TestMethod>
      </soap:Body>
    </soap:Envelope>

     

  • Tuesday, June 10, 2008 4:24 PM
     
     

    Ok. Now I am doing a POST using WebClient. Here is the response I got from the Web Service

     

    <s:Envelope xmlnsTongue Tied="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</faultcode><faultstring xml:lang="en-US">The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</faultstring></s:Fault></s:Body></s:Envelope>

     

    The request that I am using is below

     

    <?xml version="1.0" encoding="utf-8"?>

    <soap:Envelope xmlnsTongue Tiedoap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <soap:Body>

    <Test xmlns="http://SOMENAMESPACE" />

    </soap:Body>

    </soap:Envelope>

  • Tuesday, June 10, 2008 7:54 PM
    Moderator
     
     Answered

    Looks like you may be missing the SOAPAction HTTP header.

    In any case, the best way is to capture both a valid request and your non-working request using an HTTP debugging tool such as Fiddler, and compare the difference. Make sure to look at the HTTP headers as well, not just the message body.

     

     

  • Tuesday, June 10, 2008 7:58 PM
     
     

     

    Try TcpTrace tool to look at the SOAP envelope. Here is the link to download this free utility. http://www.pocketsoap.com/tcptrace/
  • Tuesday, June 10, 2008 9:27 PM
     
     

    Eugene:

     

    You da man. SoapAction Header was missing from the HTTP HEADER. Now it works like a charm. Thanks every one for the input

     

  • Thursday, October 23, 2008 5:24 PM
     
     
    Hello,
     
    Could you please post the source code of your solution with WebClient?