How to use HttpWebRequest to call a Web Service Operation that takes in a byte[] parameter?

28,226

Solution 1

it is possible, I have done it myself

First the Header settings, this can be obtained if your webservice can be executed via web and sending the parameters. I use the Developer tools from Chrome. The easy way is to review the description of the webservice (i.e. http ://myweb.com/WS/MyWS.asmx?op=Validation)

WebRequest request = WebRequest.Create(http://myweb.com/WS/MyWS.asmx?op=Validation);
request.Method = "POST";
((HttpWebRequest)request).UserAgent = ".NET Framework Example Client";
request.ContentType = "text/xml; charset=utf-8";
((HttpWebRequest)request).Referer = "http://myweb.com/WS/MyWS.asmx?op=Validation";
((HttpWebRequest)request).Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
((HttpWebRequest)request).Host= "myweb.com";
 request.Headers.Add("SOAPAction","http://myweb.com/WS/Validation");

Then the request part

string message = "a=2";
string envelope = "<?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\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
        "<soap:Body><Validation xmlns=\"http://myweb.com/WS\"><data>@Data</data></Validation></soap:Body></soap:Envelope>";
string SOAPmessage = envelope.Replace("@Data",   System.Web.HttpUtility.HtmlEncode(message));
// The message must be converted to bytes, so it can be sent by the request
byte[] data = Encoding.UTF8.GetBytes(SOAPmessage);
request.ContentLength = data.Length;
request.Timeout = 20000;
Stream dataStream = request.GetRequestStream();
dataStream.Write(data, 0, data.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
Stream inputStream = response.GetResponseStream(); 

Now you can get the incoming stream from the response

Remember to adapt the SOAP envelop and the parameters to be sent according to the description given by the page details from the webservice (i.e. http ://myweb.com/WS/MyWS.asmx?op=Validation).

Solution 2

You are using the HTTP POST/HTTP GET capability of the ASP.NET Web Service plumbing instead of sending an actual web-service call. This is a mechanism that allows you to test simple web services but it isn't really designed for use in a production application. In fact if you navigate to the web-service URL you'll find that it can't even display a test input form for that type of parameter. It might be possible to figure out a way to trick it into working, but to be honest, you should just use it the way it is intended and generate a web service proxy.

Within Visual Studio right mouse click on the project containing the client code and select Add Service or Web Reference. Then type in the URL to the web-service and it will generate a proxy. If you are using WCF it'll look something like this:

// ServiceNameClient is just a sample name, the actual name of your client will vary.
string data = "abc";
byte[] dataAsBytes = Encoding.UTF8.GetBytes(data);
ServiceNameClient client = new ServiceNameClient();
client.UploadFile(dataAsBytes);

Hope this helps.

Share:
28,226
shergill
Author by

shergill

Updated on February 27, 2020

Comments

  • shergill
    shergill about 4 years

    I am trying to call a [webmethod] from C#. I can call simple webmethod that take in 'string' parameters. But I have a webmethod that takes in a 'byte[]' parameter. I am running into '500 internal server error' when I try to call it. Here is some example of what I am doing.

    Lets say my method is like this

    [WebMethod]
    public string TestMethod(string a)
    {
        return a;
    }
    

    I call it like this using HttpRequest in C#

                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                req.Credentials = CredentialCache.DefaultCredentials;
                req.Method = "POST";
                // Set the content type of the data being posted.
                req.ContentType = "application/x-www-form-urlencoded";
    
                string inputData = "sample webservice";
                string postData = "a=" + inputData;
                ASCIIEncoding encoding = new ASCIIEncoding();
                byte[] byte1 = encoding.GetBytes(postData);
    
                using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
                {
                    StreamReader sr = new StreamReader(res.GetResponseStream());
                    string txtOutput = sr.ReadToEnd();
                    Console.WriteLine(sr.ReadToEnd());
                }
    

    This works perfectly fine. Now I have another webmethod that is defined like this

    [WebMethod]
    public string UploadFile(byte[] data)
    

    I tried calling it like this

                ASCIIEncoding encoding = new ASCIIEncoding();
                string postData = "data=abc";
                byte[] sendBytes = encoding.GetBytes(postData);
                req.ContentLength = sendBytes.Length;
                Stream newStream = req.GetRequestStream();
                newStream.Write(sendBytes, 0, sendBytes.Length);
    

    But that gives me a 500 internal error :(

  • shergill
    shergill about 15 years
    lets say I was using C++ and HttpOpenRequest.. how would I do it then?
  • Mitch Denny
    Mitch Denny about 15 years
    Not sure off the top of my head :)
  • Hiren Gondaliya
    Hiren Gondaliya almost 15 years
    If the above code works you could use Fiddler to see how the http request is constructed and then use that information to get your custom code to work.