Search code examples
c#asp.netweb-serviceshttpwebrequesthttpwebresponse

Post parameters during asmx web service call


I am trying to make a web service call to following address: http://www.webservicex.net/CurrencyConvertor.asmx?op=ConversionRate

However, I get WebException : Protocol Error. So, I need some help to find where I went wrong. Thanks.

protected void Page_Load(object sender, EventArgs e)
{
    try
    {
        string FromCurrency = "GBP";
        string ToCurrency = "ALL";

        string postString = string.Format("FromCurrency={0}&ToCurrency={1}", FromCurrency, ToCurrency);
        const string contentType = "application/x-www-form-urlencoded";
        System.Net.ServicePointManager.Expect100Continue = false;

        // Creates an HttpWebRequest for the specified URL. 
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.webservicex.net/CurrencyConvertor.asmx?op=ConversionRate");
        req.ContentType = "text/xml;charset=\"utf-8\"";
        req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        req.Method = "POST";
        req.ContentLength = postString.Length;
        req.Referer = "http://webservicex.net";

            StreamWriter requestWriter = new StreamWriter(req.GetRequestStream());
            requestWriter.Write(postString);
            requestWriter.Close();

            StreamReader responseReader = new StreamReader(req.GetResponse().GetResponseStream());
            string responseData = responseReader.ReadToEnd();

            responseReader.Close();
            req.GetResponse().Close();
    }

    catch (WebException ex)
    {
        Response.Write("\r\nWebException Raised. The following error occured : {0}" + ex.Status);
    }
    catch (Exception exc)
    {
        Response.Write("\nThe following Exception was raised : {0}" + exc.Message);
    }
}

Solution

  • I guess you are getting protocol exception because service is SOAP based. It would be easier to add service reference to that service from http://www.webservicex.net/CurrencyConvertor.asmx?WSDL. And then you could use that service as following:

    static void Main(string[] args)
        {
            ServiceReference1.CurrencyConvertorSoapClient client = new ServiceReference1.CurrencyConvertorSoapClient("CurrencyConvertorSoap");
            client.Open();
            double conversionResult = client.ConversionRate(ServiceReference1.Currency.AED, ServiceReference1.Currency.ANG);
            Console.WriteLine("{0} to {1} conversion rate is {2}", ServiceReference1.Currency.AED, ServiceReference1.Currency.ANG, conversionResult);
            client.Close();
            Console.Read();
        }
    

    [Edit] Sorry for misunderstanding. Here is how to call SOAP services without adding service reference:

    static void Main(string[] args)
        {
            HttpWebRequest request = CreateWebRequest();
            //Create xml document for soap envelope
            XmlDocument soapEnvelopeXml = new XmlDocument();
           //string variable for storing body of xml document 
           //with parameters for  FromCurrency and ToCurrency
            string soapEnvelope =
                @"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
                    <s:Body xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                        <ConversionRate xmlns=""http://www.webserviceX.NET/"">
                            <FromCurrency>{0}</FromCurrency>
                            <ToCurrency>{1}</ToCurrency>
                        </ConversionRate>
                    </s:Body>
                  </s:Envelope>";
            //add your desired currency types
            soapEnvelopeXml.LoadXml(string.Format(soapEnvelope, "USD", "EUR"));
            //add your xml to request
            using (Stream stream = request.GetRequestStream())
            {
                soapEnvelopeXml.Save(stream);
            }
            //call soap service
            using (WebResponse response = request.GetResponse())
            {
                using (StreamReader rd = new StreamReader(response.GetResponseStream()))
                {
                    string soapResult = rd.ReadToEnd(); //read the xml result
                    //you can handle xml and get the conversion result, but here 
                    //I'm outputting raw xml.
                    Console.WriteLine(soapResult);
                }
            }
    
            Console.Read();
        }
    
        public static HttpWebRequest CreateWebRequest()
        {
            //create web request for calling soap service
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(@"http://www.webservicex.net/CurrencyConvertor.asmx");
            //add soap header
            webRequest.Headers.Add(@"SOAP:Action");
            //content type should be text/xml
            webRequest.ContentType = "text/xml; charset=\"utf-8\"";
            //response also will be in xml, so request should accept it
            webRequest.Accept = "text/xml";
            webRequest.Method = "POST";
            return webRequest;
        }
    

    As you see, you should use xml for sending request. I added comments where they are necessary.