Updating the MultiDayForecast Web ControlBy Scott Mitchell
In December 2004 the National Oceanic and Atmosphere Administration (NOAA) unveiled a Web service for accessing weather forecasts for locations within the United States. To demonstrate using this service and Web services in general, I wrote an article titled Display Local Weather Forecasts with the NOAA's Web Service, in which we built a custom Web control named MultiDayForecast that displayed weather forecast information. The screen shot below shows this control in action.
In the two years since the Display Local Weather Forecasts with the NOAA's Web Service article was authored, the NOAA has made a few breaking changes to their service, thereby breaking the MultiDayForecast control. I've since updated the MultiDayForecast control to handle these breaking chnages, as well as making it easier to handle future changes. This article details the NOAA's breaking changes and the steps taken to update the MultiDayForecast control. Read on to learn more!
Breaking Change #1: An Update to the Web Service's Endpoint
When I first created the MultiDayForecast control, the WSDL document for the Web service (
http://weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl) referenced the following endpoint as the URL for the Web service:
http://weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php. (The WSDL document provides the technical details for the Web service, including information like the service's endpoint (URL), the data type formats to be exchanged, low-level protocol information, and so forth. See An Extensive Examination of Web Services for background on Web services, WSDL, and other related technologies.)
However, since publishing the WSDL document, the Weather.gov website has since implemented some sort of URL rewriting rule
that changes all requests that lack the "www" to redirects that include them. For example, if you visit
a browser, note how the browser's Address bar is rewritten to:
When visiting the URL without the "www", the website sends back an HTTP 301 response that indicates that the URL has been permanently
http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl. The browser receives this
message and automatically requests the new URL (the one with the "www").
Unfortunately, the auto-generated proxy class used by the MultiDayForecast control isn't as smart as a browser. When it gets back the HTTP 301 response it freaks out because it was expecting a valid SOAP response. It therefore displays the response as an error, saying:
System.Net.WebException: The request failed with the error message: -- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>301 Moved Permanently</title> </head><body> <h1>Moved Permanently</h1> <p>The document has moved <a href="http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php">here</a>.</p> <hr /> <address>Apache/2.0.46 (Red Hat) Server at weather.gov Port 80</address> </body></html> --.In short, we need to update the proxy class to include the "www" in the URL.
Rather than just update the proxy class, we can instead update the code to more gracefully handle any future changes to the
Web service's endpoint. To accommodate this, I updated the
method, which is the sole place the Web service is accessed from the control. Previously, I simply instantiated the proxy class
and called the
NDFDgenByDay method provided by the Web service. I've since updated the code to set the proxy class's
Url property based on a setting in the Web application's
Web.config file. If no such setting exists,
it defaults to using
With this code in place, if there's any change to the NOAA's endpoint in the future, you can simply add the following
entry to the Web application's
See Specifying Configuration Settings in
for more information.
Breaking Change #2: Handling Chunked HTTP Responses from the NOAA's Web Service
Since releasing the MultiDayForecast control, the NOAA made another change to their web server's configuration that resulted in a breaking change in the auto-generated proxy class used by MultiDayForecast. Specifically, they configured the web server to use chunked transfer encoding. As luck would have it, the proxy class doesn't like working with chunked transfer encoding and, in the face of such an encoding, will throw an HTTP protocol violation.
Rob Garrett noted this problem and provides a workaround in his blog entry, NOAA Weather Service and .NET. By default, the proxy class used by the MultiDayForecast control makes its HTTP request using HTTP 1.1, which supports chunked HTTP responses. HTTP 1.0, however, does not include support for chunked transfer encoding. Therefore, we can have the NOAA web server return non-chunked data by updating the proxy class to use HTTP version 1.0. When the NOAA's web server receives the HTTP request and sees it's version 1.0, it will not chunk the return data.
To have the proxy class to use HTTP 1.0 instead of 1.1, we need to override the proxy class's
method, which returns the
HttpWebRequest used to issue to HTTP request to the Web service. The following code,
taken from Rob's blog entry, shows the change we need to make:
This code could be added to the auto-generated
Reference.cs file in the
Web References folder, but
doing so would result in our customizations being lost the next time the proxy class was auto-generated. When extending auto-generated
code use one of the following two approaches:
- Use Inheritance - create a class that derives from the auto-generated class and add the additional properties/methods/etc. to this derived class. In your code, reference the derived class instead of the auto-generated one. This technique works equally well in ASP.NET 1.x and 2.0.
- Use Partial Classes - partial classes are a feature new to .NET 2.0 and provide a way for a single class to be spread out across multiple files.
ndfdXMLWithHTTP1Supportthat derived from
ndfdXML, the auto-generated proxy class. I also put it in the same namespace as the auto-generated proxy class (
Lastly, we need to update the
GetDailyForecast to now use the
ndfdXMLWithHTTP1Support class instead of
Since its creation in March 2005, the MultiDayForecast control has encountered two hiccups due to breaking changes to the NOAA's weather forecast Web service. In particular, the Web service no longer allows URLs that lack the "www". When receiving such requests, the web server responds with an HTTP 301 response indicating the new URL to use. This non-SOAP response results causes the auto-generated proxy class to raise an exception. To fix this problem we needed to update the URL used by the proxy class to include the "www" portion.
The other breaking problem had to do with the Web service returning the SOAP response using chunked transfer encoding. Unfortunately, Microsoft's SOAP proxy class cannot correctly handle the chunked encoding and raises an exception. We can circumvent this by using the HTTP 1.0 protocol when making the Web service request. Since HTTP 1.0 does not support chunked transfer encoding, the Web service does not chunk its returned data and the proxy class can parse the content correctly.
Thanks to Rob Garrett, Martin Woods, and other alert 4Guys visitors who notified me of these problems and offerred suggestions and workarounds for fixing them...