0
votes

I have the followind webservice defined.

       [WebMethod]
        public String sendBytes(byte[] a)
        {
            return "good";
        }

I am able to call it successfully using the Webservice proxy class.

However I am unable to send a HTTP POST with binaries to this web method. I tried this:

      try
           {
               HttpWebRequest request = HttpWebRequest.Create(address) as 
               HttpWebRequest;

            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            //request.ContentLength = 0;


            var postData = "xxx";         

            var data = Encoding.UTF8.GetBytes(postData);

            request.ContentLength = data.Length;

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }
            var response = (HttpWebResponse)request.GetResponse();
            Console.Write("Sending request\n\n");
            var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
            String x = Console.ReadLine();

and I got this

System.NullReferenceException: Object reference not set to an instance of an object. at System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection collection) at System.Web.Services.Protocols.HtmlFormParameterReader.Read(HttpRequest request) at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

The thing is I can send Strings using this method, but not binary data. The definition in the webservice POST Example is also wierd.

http://localhost:50178/WebService1.asmx?op=sendBytes

I am grateful for ANY help or suggestions on this topic. Thx for reading :)

Edit: Thank you for your quick response.

I think I have solved the null exception, I think the cause of it is because it cant find the param for the value that I am sending. But I have another problem now:

System.ArgumentException: Cannot convert ef to System.Byte. Parameter name: type ---> System.FormatException: Input string was not in a correct format. at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) at System.Byte.Parse(String s, NumberStyles style, NumberFormatInfo info) at System.String.System.IConvertible.ToByte(IFormatProvider provider) at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at System.Web.Services.Protocols.ScalarFormatter.FromString(String value, Type type) --- End of inner exception stack trace --- at System.Web.Services.Protocols.ScalarFormatter.FromString(String value, Type type) at System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection collection) at System.Web.Services.Protocols.HtmlFormParameterReader.Read(HttpRequest request) at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

Here is the code:

          try
        {
            HttpWebRequest request = HttpWebRequest.Create(address) as 
           HttpWebRequest;

            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            //request.ContentLength = 0;


            var postData = "a=";         

            var data = Encoding.UTF8.GetBytes(postData);
            byte[] bytedata = new byte[] { 0x65,0x66};
            request.ContentLength = data.Length + bytedata.Length;

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
                stream.Write(bytedata, 0, bytedata.Length);
            }
            var response = (HttpWebResponse)request.GetResponse();
            Console.Write("Sending request\n\n");
            var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

Edit 2: I have tried Aaron's suggestion but it did not work.

Here is the edited code:

        try
        {
            HttpWebRequest request = HttpWebRequest.Create(address) as 
          HttpWebRequest;

            request.Method = "POST";
            request.ContentType = "application/octet-stream";

            //request.ContentLength = 0;


            var postData = "a=";         

            var data = Encoding.UTF8.GetBytes(postData);
            byte[] bytedata = new byte[] { 0x65,0x66};
            request.ContentLength = data.Length + bytedata.Length;

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
                stream.Write(bytedata, 0, bytedata.Length);
            }
            var response = (HttpWebResponse)request.GetResponse();
            Console.Write("Sending request\n\n");
            var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

Gave the following error:

System.InvalidOperationException: Request format is invalid: application/octet-stream. at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

Reference :How can I make a local file as body of an HttpWebRequest?.

The thing is i tried changing the url, because if the problem was the packet not being formed well I would get the same error, but it dint. Could it be my webservice being wrong somewhere?

1

1 Answers

1
votes

Try setting the request.ContentType to application/octet-stream. This content type is used to signal that the request body contains arbitrary binary data.

Remember that HTTP is a text based protocol that uses ASCII encoding in it's messages. In your test data 0x65 and 0x66 are 'e' and 'f' in which is why the exception you get says "Cannot convert ef to System.Byte". The bytes you are trying to send are getting encoded to ASCII, therefore becoming a string, where your endpoint is expecting bytes.

Edit:

You could also try using a multipart/form-data request. Example of how to do it with C# is here:

https://gist.github.com/bgrins/1789787

References:

Why Http Protocol is designed in a plain text way

Which Mime Type to use for a binary file