How many time did we think about having simple weather forecast displayed on our web site without depending on third party? Weather data offered by National Weather Service is free and it can be processed and displayed in the way we want.
So, lets start with basic question – what’s URI of the web service? The web service can be found http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php?wsdl.
If you want more information visit this page. It’s useful to read NOOA’s documentation which, in many details, explain how to use their SOAP weather service. What I am going to do today is not building weather forecast solution (I left this to others), but calling web service and parsing data returned in SOAP format. The forecast data is returned as XML string that will be used to populate forecast objects.
Start Visual Studio 2010 and create new class library project. We can call this project Weather (see Figure 1).
At this step we need to create service reference that will give us all we need in order to get data from weather server. To do that, right click on Weather project you just created in your solution, and click Add Service Reference (see figure 2).
Enter http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php?wsdl as address and click Go. The service will be discovered and we will be able to add service to our project (see Figure 3).
If you open app.config, you will notice that basicHttpBinding bindings will be used. We will use BasicHttpBinding to configure and expose endpoints that are able to communicate with ASMX-based Web service. You can find all files of Weather project in ZIP file. Add files to your project. as you can see the code is very self-explanatory which is the reason I will not talk about that part of the project.
What I am going to talk about is default binding that I have just mentioned above. BasicHttpBinding is not good enough in this case and the reason is - encoding. In other words, web service is returning different encoding than what we have defined in app.config. If you have time, you can build the project and try to get some weather web service data returned to your application. As result to service call, you will get an encoding error. The error message should be something like this:
The content type text/xml; charset=ISO-8859-1 of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly.
What should we do now? I do not know if building custom text message encoder is only solution for this problem but I know for sure that it worked for me. In the next step we will add custom text message encoder and do some web.config modification (we will add web site later).
This time we are lucky because Microsoft provided us with code and explanation how to build custom encoder for WCF. The problem is caused by weather web service returning ISO-8859-1 encoded data. As such we cannot read it on client side because WCF supports only the UTF-8, UTF-16 and Big Endean Unicode encodings. The custom message encoder contains not only message encoder but also description of binding element that we will use instead of basicHttpBinding.
Add Microsoft CustomTextMessageEncoder to your solution. At this point your solution should look like this assuming you downloaded weather.zip file that contains solution projects and files.
We do not need to add reference to our library project, but we need to add CustomTextMessageEncoder to web site project so we can make changes to ServiceModel section of web.config file. In order to use CustomTextMessageEncoder, add following at the bottom of system.ServiceModel section:
There is already BasicHttpBindig defined in your web configuration files so we will need to add <customBinding>....</customBindig> section where we will defined correct encoding of the messages sent from National Weather Service.
This time we have correct ISO-8859-1 encoding so our application will be able to receive messages from the service. There is one more thing. Depending on collection of data you want to receive from NOAA you will have too adjust maxReceivedMessageSize and maxBufferSize of your binding because weather data returned could be very large.
<customTextMessageEncoding encoding="ISO-8859-1" messageVersion="Soap11WSAddressing10"/>
I almost forgot to tell you how to call actual service from your Weather library you created in Step 1.
Weather.ServiceReference1.ndfdXMLPortTypeClient service =
Once when you created object of ndfdXMLPortTypeClient it's easy to receive data back from National Weather Service.
this.StringXmlResult = service.LatLonListZipCode(zipCode);
PointInfo = new Point(this.StringXmlResult);
if(PointInfo!=null && PointInfo.IsProcessed)
if (this.Forecast == ForecastType.Hours_12)
this.StringXmlResult = service.NDFDgenByDay(PointInfo.Latitude, PointInfo.Longitude, DateTime.Now, this._numberOfDays.ToString(), "12 hourly");
this.StringXmlResult = service.NDFDgenByDay(PointInfo.Latitude, PointInfo.Longitude, DateTime.Now, this._numberOfDays.ToString(), "24 hourly");