I’d like to talk about difficulties you may encounter when retrieving and using GeoRSS (or in fact any XML data) in an application built on the .NET framework—including those built with the new ArcGIS API for Silverlight/WPF. The basics of using XML feeds involve:
- Constructing a URL pointing to the data location;
- Using a .NET framework object, such as WebClient, to read the data;
- Decoding the XML data and doing something with it
Using the ESRI Proxy Page
The first roadblock you’ll run into is that of cross-domain security—that is, when your base map data is on one server (e.g. ArcGIS Online) but the XML data you want is on another. This is considered a security risk and is generally forbidden by web browsers and network-access object models such as those in Microsoft’s Silverlight or Adobe’s Flex.
A couple of solutions are:
- Add an access policy file on the XML server as documented near the bottom of this page.
- Use a proxy page to access the data, as documented here.
The policy file is the easier solution, but it is not normally under your control as a developer. Setting up a proxy page involves downloading it and installing it into the web directory of your solution:
To use it, use its local URL along with a query string parameter for the remote web page containing the XML data you want; for example: http://localhost/GeoNetworkCatalog.Web/proxy.ashx?http://geonetwork3.fao.org/geonetwork/srv/en/rss.search?georss=gml
There are two question-mark parameter delimiters here; the first one is used by the proxy page to determine the real location of the XML feed. The second question mark is interpreted by the server hosting the XML data. This will trick the web browser into thinking the data you want is on the local web server, not on a remote and insecure domain.
How do we use the proxy page to get data? .NET provides an object for this, called WebClient. Setting up the download involves just a few preparatory lines of code:
// sURL is the proxy page plus URL for the remote GeoRSS feed
Uri uriGeoRSS = new Uri(sURL, UriKind.Absolute);
WebClient wcGeoRSS = new WebClient();
// grss_HandleString is an event handler called when the data is available
wcGeoRSS.DownloadStringCompleted += new DownloadStringCompletedEventHandler(grss_HandleString);
wcGeoRSS.DownloadStringAsync(uriGeoRSS); What you do with the downloaded GeoRSS data is up to you. Your event handler will receive the feed data as XML, so you can use standard .NET XML objects to break it into usable bits:
private void grss_HandleString(object sender,
DownloadStringCompletedEventArgs args) {
if (args.Error == null) {
XElement xdocGeoRSS = XDocument.Load(
new StringReader(args.Result)).Root.Element("channel");
// Display header info
hlPageLinkMain.Content = (string)xdocGeoRSS.Element("title");
hlPageLinkMain.NavigateUri =
new Uri((string)xdocGeoRSS.Element("link"));
// Etc...
There’s a problem, however: the proxy page often fails to properly download XML data. So you may need to modify the page to handle GeoRSS XML properly.
Modifying the ESRI Proxy Page
If you’ve decided you need a proxy page to get XML data for your application, you may have downloaded and tried the ESRI proxy page.
There’s a problem with the page as it’s implemented, and it’s in the one line that does all the work of the proxy page:
byte[] outb = br.ReadBytes((int)serverResponse.ContentLength);
The ContentLength property returns the value of the HTTP “Content-Length” header; but a quick web search shows that this property is commonly incorrect or missing. A more robust approach is to read data from the response stream until there’s none left:
while ((array = reader.ReadBytes(4096)).Length > 0) {
// Append this 4K chunk to the previously read chunks
}
The resulting modified is available here on ArcScripts..
Local data and absolute URLs
While developing your application, you’ll probably read your target XML data source many, many times; but you probably won’t need the latest data. You might want to temporarily use a static local snapshot of the data in order to avoid putting a heavy load on the remote server.

The snag is that the WebClient methods need an absolute URL path, not a relative one. You could just hardcode the XML file’s web server location in your call to WebClient.DownloadStringAsync; or you could add a little code to convert a relative file path to an absolute URL location. There’s a short, useful blog entry on just this subject at the .NET Developer’s Journal website.
This small routine will convert a local “file://” reference to an “http://” style reference. With this approach, it’s easy to use a local file in the same manner as a remote XML feed. And using conditional compilation statements, switching between local and remote sources is as simple as changing your project configuration from the Visual Studio dropdown list.

There is, of course, much more involved in effectively accessing and using XML data in your .NET application. But hopefully these tips will help route you around some of the trickier snags in the process.
Contributed by Mark D.