What is this?

This is basically where I write down stuff that I work with at my job as a GIS Technical Analyst (previously system administrator). I do it because it's practical for documentation purposes (although, I remove stuff that might be a security breach) and I hope it can be of use to someone out there. I frequently search the net for help myself, and this is my way of contributing.

Sunday, October 28, 2012

Using ESRIs proxy.ashx for all maps in Geocortex Essentials

I can't believe it's been over a year since I last posted. Oh well. Time flies.

Lately I've been working on a project using the eminent map application construction kit from Lattitude Geographics called Geocortex Essentials. I'm using it to presnet data and maps from ArcGIS Server and various WMS OGC services. 

Some map services are protected to avoid excessive traffic or abuse, and depending on the viewer (Javascript or Silverlight for instance) you may need to use a reverse proxy to relay data from your Geocortex Essentials website to the mapserver which is hosting the maps you need.

I have been using ESRIs simple proxy.ashx with a number of ArcGIS Server sites without any problems. However - when trying to access WMS services running on Geoserver or Mapserver I would get a response from getcapabilities, but no png or jpegs would appear. Turning on debug in IIS revelade the following error:

Exception Details: System.ArgumentOutOfRangeException: Non-negative number required.

I loaded proxy.ashx into Visual Studio and had a look, and it seems like certain servers will not return the length of the binary stream for the image it returns causing an exception on the following line (the value it returns is -1). The following line is the culprit:

    byte[] filedata = new byte[request.inputstream.length];

Apparently the value is optional, so I suppose it's not really a bug.

I did a quick adjustment to the code to be able to read images regardless of the request.inputstream.length value. If you need to do the same thing - simply replace the following code in proxy.ashx:

  {
      // Binary response (image, lyr file, other binary file)
      BinaryReader br = new BinaryReader(byteStream);
      byte[] outb = br.ReadBytes((int)serverResponse.ContentLength);
      br.Close();

      // Tell client not to cache the image since it's dynamic
      response.CacheControl = "no-cache";

      // Send the image to the client
      // (Note: if large images/files sent, could modify this to send in chunks)
      response.OutputStream.Write(outb, 0, outb.Length);
    }

with this:

  {
      // Binary response (image, lyr file, other binary file)
      MemoryStream ms = new MemoryStream();
      BinaryReader br = new BinaryReader(byteStream);
      byteStream.CopyTo(ms);
      br.Close();

      // Tell client not to cache the image since it's dynamic
      response.CacheControl = "no-cache";

      // Send the image to the client
      // (Note: if large images/files sent, could modify this to send in chunks)
      response.OutputStream.Write(ms.ToArray(), 0, ms.ToArray().Length);
  }

Make sure you configure the proxy to run in a .net 4.0 application pool on IIS.

Thats's all. Now the proxy seems to relay any kind of image it needs to.

Modified proxy.ashx can be downloaded here.