locked
Reading A Raw Binary Post Buffer RRS feed

  • Question

  • I have a legacy client.   It sends a URL and then a binary post buffer (not WCF encoded binary,  it's own format).    I want to map that to a WCF method for that URL.   And then I want to read the buffer directly to deserialize the message.   The only thing that tells me the message type is the URL.   So how does one do this in a WCF way (without resorting an ASP IHttpHandler of some sort)


    sjz
    Thursday, August 4, 2011 8:37 PM

Answers

  • You can use the raw programming model for that. Essentially, if you declare an operation with a single parameter of type Stream in a WCF web endpoint (i.e., one with the webHttpBinding and the webHttp behavior - or the one added by the WebServiceHost which is exactly the same thing), then all the request body will be delivered to your application as that stream. You can find more information about it at http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-receiving-arbitrary-data.aspx.

      public class Post_fc8cbad8_a8fc_46d6_b15f_5ae712ca56cd
      {
        public class Order { }
        public class Client { }
        [ServiceContract]
        public interface ITest
        {
          [WebInvoke(UriTemplate = "/ProcessOrder")]
          void ProcessOrder(Stream input);
          [WebInvoke(UriTemplate = "/AddClient")]
          void AddClient(Stream input);
        }
        public class Service : ITest
        {
          public void ProcessOrder(Stream input)
          {
            Order order = ParseOrder(input);
          }
          public void AddClient(Stream input)
          {
            Client client = ParseClient(input);
          }
          Order ParseOrder(Stream data) { return null; }
          Client ParseClient(Stream data) { return null; }
        }
        public static void Test()
        {
          string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
          WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
          host.Open();
          Console.WriteLine("Host opened");
    
          WebClient c = new WebClient();
          c.Headers[HttpRequestHeader.ContentType] = "application/octet-stream";
          byte[] order = new byte[100];
          Random rndGen = new Random();
          rndGen.NextBytes(order);
          c.UploadData(baseAddress + "/ProcessOrder", order);
    
          c = new WebClient();
          c.Headers[HttpRequestHeader.ContentType] = "application/x-clients";
          byte[] client = new byte[1000];
          rndGen.NextBytes(client);
          c.UploadData(baseAddress + "/AddClient", client);
    
          Console.Write("Press ENTER to close the host");
          Console.ReadLine();
          host.Close();
        }
      }
    
    


    Carlos Figueira
    Thursday, August 4, 2011 9:35 PM

All replies

  • And to be clear,  I would like to have a different method for each URL.   I am not adverse to having an endpoint, look at the URL and "dispatch" to the appropriate method based on some lookup table built from code attributes.


    sjz
    Thursday, August 4, 2011 8:38 PM
  • You can use the raw programming model for that. Essentially, if you declare an operation with a single parameter of type Stream in a WCF web endpoint (i.e., one with the webHttpBinding and the webHttp behavior - or the one added by the WebServiceHost which is exactly the same thing), then all the request body will be delivered to your application as that stream. You can find more information about it at http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-receiving-arbitrary-data.aspx.

      public class Post_fc8cbad8_a8fc_46d6_b15f_5ae712ca56cd
      {
        public class Order { }
        public class Client { }
        [ServiceContract]
        public interface ITest
        {
          [WebInvoke(UriTemplate = "/ProcessOrder")]
          void ProcessOrder(Stream input);
          [WebInvoke(UriTemplate = "/AddClient")]
          void AddClient(Stream input);
        }
        public class Service : ITest
        {
          public void ProcessOrder(Stream input)
          {
            Order order = ParseOrder(input);
          }
          public void AddClient(Stream input)
          {
            Client client = ParseClient(input);
          }
          Order ParseOrder(Stream data) { return null; }
          Client ParseClient(Stream data) { return null; }
        }
        public static void Test()
        {
          string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
          WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
          host.Open();
          Console.WriteLine("Host opened");
    
          WebClient c = new WebClient();
          c.Headers[HttpRequestHeader.ContentType] = "application/octet-stream";
          byte[] order = new byte[100];
          Random rndGen = new Random();
          rndGen.NextBytes(order);
          c.UploadData(baseAddress + "/ProcessOrder", order);
    
          c = new WebClient();
          c.Headers[HttpRequestHeader.ContentType] = "application/x-clients";
          byte[] client = new byte[1000];
          rndGen.NextBytes(client);
          c.UploadData(baseAddress + "/AddClient", client);
    
          Console.Write("Press ENTER to close the host");
          Console.ReadLine();
          host.Close();
        }
      }
    
    


    Carlos Figueira
    Thursday, August 4, 2011 9:35 PM