SHORTS : Consuming a WCF (ASMX) web service in WinRT

APPLIES TO: Windows 8.x and Windows Phone RT

Here’s another brick-wall I had faced recently – consuming a WCF service in a WinRT app. When Silverlight was around, using a WCF service was really easy, one just had to add a Service Reference to the WCF service hosted online, and then Visual Studio would expose the methods of the Service by means of a Proxy class. This feature no longer exists, and one has to make use of a work-around to create a client that consumes the web service.

The solution is to create and use an instance of the HttpClient class and use that to send SOAP requests to the ASMX operation. As a demo, I’m using the weather service hosted at http://wsf.cdyne.com/WeatherWS/Weather.asmx, and the operation used is GetCityWeatherByZIP. The first step, naturally is to setup the HttpClient object –


var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
httpClient.DefaultRequestHeaders.Add("SOAPAction", "http://ws.cdyne.com/WeatherWS/GetCityWeatherByZIP");

Once this is done, the SOAP request is framed and a response is sought from the web service –

var soapXml = "<?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><GetCityWeatherByZIP xmlns=\"http://ws.cdyne.com/WeatherWS/\"><ZIP>23454</ZIP></GetCityWeatherByZIP></soap:Body></soap:Envelope>";
var response = httpClient.PostAsync("http://wsf.cdyne.com/WeatherWS/Weather.asmx", new StringContent(soapXml, Encoding.UTF8, "text/xml")).Result;
var content = response.Content.ReadAsStringAsync().Result;

The variable content contains the XML response sent by the web service, which can then be parsed as an XDocument to get the desired information.

XDocument responseXML = XDocument.Parse(content);
XElement city = new XElement(responseXML.Descendants(XName.Get("City", "http://ws.cdyne.com/WeatherWS/")).FirstOrDefault());
XElement temperature = new XElement(responseXML.Descendants(XName.Get("Temperature", "http://ws.cdyne.com/WeatherWS/")).FirstOrDefault());
XElement wind = new XElement(responseXML.Descendants(XName.Get("Wind", "http://ws.cdyne.com/WeatherWS/")).FirstOrDefault());
//Use the elements in any way you want
responseView.Text = city.Value + "\n" + temperature.Value + "\n" + wind.Value;

Leave a comment