WebObject.ManageLifetime Redux

Posted by Dave Bouwman | Posted in .NET, ASP.NET, ArcGIS Server, ESRI | Posted on 31-05-2006

0

After my previous post, I got an email from a reader internal to ESRI (since it was an email and not a comment, I’ll allow them to remain anonymous) pointing me to two new (April 10th) techincal articles which address lifetime managment.

Problem:  Microsoft .NET Framework applications explicitly manage references to remote COM objects

FAQ:  Do I need to explicitly manage references to remote COM objects in a Microsoft .NET Framework application? (Answer is now No.)

If you apply the referenced patches from Microsoft (they are included in XP Sp2), you no longer need to explicitly manage the lifetime of these objects.

For all my digging on the ESRI site, one thing that led me astray was reading the “Managing Server Resources in ArcGIS Server .NET Applications” white paper (October 2005), which desribes using the IDisposable pattern and WebObject.ManageLifetime. Since this was a “whitepaper”, I assumed it was the last word on this, and did not look further. Hopefully they can get this new information into this document or at least it’s description.

Anyhow – thanks for pointing me in the right direction. Since I am running XP Sp2, it does explain why adding or removing WebObj.ManageLifetime made no apparent difference.

Object Oriented Design & ArcGIS Server DCOM: Incompatible?

Posted by Dave Bouwman | Posted in .NET, ASP.NET, ArcGIS Server | Posted on 30-05-2006

0

One of the big promises of ArcGIS Server is that you can build web services that access ArcObjects. This opens up all kinds of interesting options. But some of the requirements of using those (DCOM) ArcObjects cause problems in object-oriented designs.
 
To illustrate the problem, I’ll talk about a web service that I’m currently working on.
 
Map Series Web Service
The concept is quite simple: create a web service that will generate 1:100K PDF maps, based on the selection of a 1:100K tile. The front end will be an ArcIMS powered portal, and since the PDF production takes a few minutes, the resultant map will be emailed to the user. All layout etc is handled in the MXD – the only thing the web service does is swap out some text for titles, and zoom to the correct tile. This is about the simplest “real-world” web service.
 
Since I like to keep my code organized, I created some business objects to actually do the work behind the scenes (this also makes it much more testable, but that’s another post)…
 
SheetService Class
This class actually handles the request – the asmx just spins up an instance of this class and let’s it do the work. It reads needed info from a config file, creates the other helper classes (below), connects to a SOC, locates the tile feature, zooms the map, and creates the PDF and shoots off the email.
 
MapTitle Class
This parses map title information from an XmlNode passed to it by SheetService as it is reading web.config. It is responsible for setting the text of the title elements in the layout, and then re-setting them back to their original “tags” so they can be located the next time the context is used.
 
TileLayer Class
This class is involved with holding settings from the config file which specify information about the tile layer itself – the layername, the dataframe it is contained in, the field to be used for the Tile Title.
 
TileLocator Class
This class handles drawing the active 1:100K tile onto the locator map. It also parses config info from a node passed to it by SheetService as it is reading web.config. Similar to the MapTitle, after the PDF is generated, this class needs to delete the tile element so that it will not be on the map the next time the context is used.
 
DCOM & ServerContext
The hitch is that with ArcGIS Server, whenever you explicity create a new object, you must do it in the SOC – via context.CreateObject(”esriWhatever.SomeClass”).  This way the actual object is created in the SOC, and you get back a proxy which communicates back via DCOM. Thus any class that uses ArcObjects also needs access to IServerContext. In order to make sure that these objects will be disposed of correctly, you also need to call WebObject.ManageLifetime once you have a pointer to the proxy. The same goes for objects you create implicitly (i.e. by casting). Thus you also need access to a WebObject.
 
The question is: How to we manage the lifetimes of ArcObjects (and their proxies) in our custom business objects?
 
Solutions?
One option is to pass along both the Server Context and web object into any methods. Passing in a webobject instance is particularly thorny, since it is typically created via a using () block, anything you add into it will be cleaned up when it is disposed. Thus you must be very careful about accessing properties which may expose ArcObjects (proxied) for fear that the webObject disposed, and thus you get null back. This sort of thing could get really really ugly to debug.
 
The next option is to pass in a ServerContext only, and create a webObject as needed, in it’s own using block. This makes for cleaner method signatures, but now you are ensuring that you dispose all of your created ArcObjects when the method completes, but what if you need to hold onto some of those objects for longer than your method call? Next!
 
Much of the example code, and lots of code in the forums seems to go with the “Big-Ugly-Function” design philosophy. Simply stuff everything you need to do in one large function, wrap that in a using ( WebObject webObj = new WebObject(true) ) block, call CreateObject and ManageLifetime every other line, and you’re off. Just because this is a common pattern does not change the fact that it’s evil. Re-use? Nah. Unit Testing? Good Luck! Next!
 
The other option I can come up with is to write all our AGS logic as COM objects that run in the SOC. This is somewhat compelling (and the recommended pattern for Cross-Product Development), as you can do away with all the CreateObject and ManageLifetime stuff, but it would seem that you then have other problems in relating those classes into whatever you are doing on the “client” side of the DCOM connection. And what of the case when only part of your object model is involved in the geospatial aspect of things?
 
What are you doing?
For this project, I’ll likely go with wrapping the classes into COM, but I’m very interested in what other people are doing to address this issue. I doubt that I’m the only developer who wants to be able to have a nice clean object model to work with, and DCOM certainly adds another layer of complexity.

Cross Post Test

Posted by Dave Bouwman | Posted in General | Posted on 30-05-2006

0

Test to see if this correctly cross posts to ArcDeveloper.net

New Blog URL & HttpHandler Redirection

Posted by Dave Bouwman | Posted in ASP.NET, dasBlog | Posted on 29-05-2006

0

After much messing around trying to get the dasBlog CAPTCHA to work when my blog was running under a .NET 2.0 application, I finally gave up and moved it out to it’s own sub-domain (blog.davebouwman.net). This way both sites can happily coexist – one in 1.1 and the other in 2.0, and CAPTCHA will reliably work.

The main feed is via FeedBurner, so it has been updated. The other problem was avoiding 404 errors for people who have bookmarks to the site, or who come in from Google. The basic problem was how to redirect all requests to the old Url to the new Url.

The pattern looks like this:

blog.davebouwman.net/blog/SomeContent.aspx –>  over to blog.davebouwman.net/SomeContent.aspx

This is just the place for a HttpHandler. The handler itself simply intercepts requests, and transforms the Url as noted above, and then redirects the client browser to the new location. Since the main site runs in .NET 2.0, I created a class in App_Code, and had it implement IHttpHandler.

The redirection code for the handler is super simple:

  public void ProcessRequest(HttpContext context)

       {

           context.Response.Cache.SetCacheability(HttpCacheability.Public);

          //re-map the Url

           string inputUrl = context.Request.Url.AbsoluteUri;

           string redirUrl = “”;

        

           if (inputUrl.Contains(”http://www.”)) {

               //drop the /blog

               redirUrl = inputUrl.Replace(”/blog”, “”);

               //repoint the subdomain

               redirUrl = redirUrl.Replace(”http://www.”, “http://blog.”);              

           }

           context.Response.Redirect(redirUrl, true);

       }

Next is register the handler in web.config. The syntax for adding the handler into Web.Config is not exactly clear: Depending on where you handler is implemented, there are two ways to specify the type:

1) If the implementation is in another assembly, then you must put the assembly name after the type. This is what I most commonly found whe Googling, and is standard practice for .NET 1.1

    <httpHandlers>
      <add verb=”*” path=”~/blog/*.*” type=”SomeNamespace.SomeHandler,SomeAssembly” />
    </httpHandlers>

2) If the implementation is in App_Code (ie it’s in the running assembly), you do not need to specify the assembly name. This makes sense as in ASP.NET 2.0, there is no assembly name! But this is not exactly clear.

     <httpHandlers>
      <add verb=”*” path=”~/blog/*.*” type=”BlogRedirectHandler” />
    </httpHandlers>

After I got this sorted out, everything was working smoothly on my home system. However, when I moved the code to my hosting provider (www.webhost4life.com), the handler would not work.

Solution
I’ll jump to the conclusion, and if you’re having strange problems with web.config & HttpHandlers, read the Details section below.

The underlying issue was the in order to have dasBlog live inside a .NET 2.0 web site, I had to create a separate .NET application at blog.davebouwman.net/blog. Even though I removed the folder, IIS was still thinking that the application existed. Since it’s a hosted system, and I did not have direct access to the IIS manager, I had to muddle around in their “.NET Application” tool – where I finally saw that the application was still mapped in IIS. Once I deleted this application, everything worked.

More Details…

I had moved the /blog folder out of my main site, and did not intend to have a /blog folder at all – the HttpHandler would match the Url pattern, and handle the request without needed a real folder. Only when I made a request, I got an ASP.NET Error stating that the requested folder does not exist. While technically accurate, this seemed like an odd error because I did not get it on my home system.

I then re-created the /blog folder, when I got a “Could not create type” error, which would show the handlers section from web.config. No matter how I setup the handler  – in App_Code or external assembly, it would not load the handler.

So, I suspected that this was somehow related to the fact I used to have an application in /blog, so I changed the path in the handler to /junk/*.* and fired off a request. And it worked. This narrowed it down to something related to the /blog folder. From there I just banged around in the site manager tools that I have access to, and finally was able to delete the “.NET Application”.

So – if you are having issues with httpHandlers, getting “Could not Create Type” or “could not create assembly” errors, make sure the path you are trying to handle is not registered as it’s own application.

Holy Comment Spam!

Posted by Dave Bouwman | Posted in General, dasBlog | Posted on 20-05-2006

0

I had turned CAPTCHA off in dasBlog, as it was acting flaky running under a .NET 2.0 web site. I expected some spam to creep in, at which point, I’d deal with it. I’ve been out of town this week, and more or less off line. I just got back to find that I now have 1000’s of spam comments! Conveniently, dasBlog stores the comments separately from the content (in the dayfeedback.xml files), so cleaning up is not that big a deal – just find the big ones (50k as compared to the usual 1k) and delete them.

But, I guess it’s time to deal with the problem and get this working consistently under .NET 2.0.

State-Wide Enterprise GIS Development Project

Posted by Dave Bouwman | Posted in .NET, ArcGIS Devt, ArcGIS Server, ESRI | Posted on 09-05-2006

0

I wanted to give a shout out to the entire proposal team at my company, as we have finally signed the contract to build the Pennsylvania Enterprise Forest Managment system. I’m very excited about this award, as I was very involved in the technical aspects of the proposal, and led the technical presentation to the state (a rather harrowing experience). I’ll also be leading the system design and development from our Fort Collins office. 

Since this is a 3 year contract, we’ll be building in .NET 2.0, using ArcGIS  9.2 and using a mix of Desktop/Engine (via Citrix) for complex geometry editing, and Server/IMS for most other functionality. We’ll see if we can sneak the Mobile ADF into the mix as well ;-)

Like the previous enterprise system’s we’ve built, we’ll be implementing this as set of tools/applications which work against a “secured” geodatabase. By secure, I mean a set of column level editing permissions, which matrix into a set of workflow permissions, using Active Directory to manage identity and access and implemented with Feature Class extensions. This allows us to implement complex, multi-stakeholder, multi-step business processes, while still enforcing all the required business logic – and we do it at the geodatabase level so it can not be circumvented. To make things more interesting, this time we’ll need to make this work in both a desktop and ArcGIS Server envionment.

Sound interesting? Send me your resume! – we’re looking for developers and a business analyst.

We’re just starting up the project, and will be doing some system level architecture up front, and then jumping into the functional modules. This will be my main focus for the next few years, so there will be plenty of postings on the technical aspects of how we are building this system.

IE7 Beta 2 Breaks ArcToolbox

Posted by Dave Bouwman | Posted in ESRI, Software | Posted on 05-05-2006

1

Just a heads up to anyone else thinking of running IE7 Beta 2 – it will break ArcToolbox. I had not connected the dots on this, but ESRI Tech support mentioned this as a possible cause of my problem, and they were right.

The symptom is that when you try to open an GP Task by double clicking on in – either in a model, or in ToolBox, ArcMap will crash. No useful message, just a “Please report this to Microsoft” pop-up box. As soon as you un-install IE7, it works just fine.

This is a pain because having tabs in IE made working with our Team System portals much nicer than having a bunch IE sessions open. I have not tried running IE7 without installing it, as J noted on his blog next week. It would be cool if this fixes the problem.

Development Podcasts…

Posted by Dave Bouwman | Posted in .NET | Posted on 03-05-2006

0

Over the last few weeks I’ve been getting more into Podcasts, mainly
because it’s something to keep my mind active while taking Kai on long
walks in his stroller.

Anyhow – I’ve checked out A Very Spatial Podcast, and while this is germane to GIS, it’s not really my thing. And the ESRI Podcasts (Instructional and Speaker series) are somewhat interesting, but certainly aimed at more of their core end-user audience.

I was looking for something more developer oriented, something I could
use tomorrow, or at least sometime in the next 6 months. Here’s what
I’ve found and have subscribed to via iTunes…

HanselMinutes
Scott Hanselman is a whip smart .NET developer, who writes the ComputerZen
blog (you should read this). These are short (30 minute) discussions
that can cover all kinds of interesting .NET and Windows related stuff.
I highly recommend the Xml show, the Functional Testing show, and Code
Generation show. This is very compact information, and I typically
listen to the shows a few times to absorb it all. This is the first
podcast that I’ll listen to.

DotNetRocks
I had given this a look a year or so ago, but the audio quality was not
too great, and I think there was a huge focus on
“wont-this-be-cool-at-.NET-2.0″ when I was still working in v1.1. I
gave it another go, and I have to say this is really good. It’s not as
focused as the HanselMinutes, but still covers great topics – this
weeks topic is “Atlas”.

Polymorphic Podcast
This is another .NET Podcast, with recent shows on Architecting Ajax
Applications, User Experience, ASP.NET Event Lifecycle. Typically 30
minutes in length.

That’s what I’ve got in the iPod right now – any other great .NET developer podcasts I’ve missed?