Web References & WSE 2 in Visual Studio

Posted by Dave Bouwman | Posted in .NET | Posted on 26-08-2005

0

Maybe this is a well known, or even documented issue, but I’m jotting it down so I don’t forget it –

If you have a reference set to Microsoft Web Service Enhancments (WSE 2.0), and you add a web reference to a project in VS.NET, by default the proxy class will inherit from Microsoft.Web.Services2.WebServicesClientProtocol. This is so that you get the WSE 2.0 Enhancements.

However, by default, the URL Behavior is set to “static”, which means the URL is hardcoded in the proxy…

But this is not too handy for moving things between dev / test / production. But VS lets you change the URL Behavior to “Dynamic”

It re-creates the proxy class when you do this. Only now, it inherits from System.Web.Services.Protocols.SoapHttpClientProtocol, which is not what you wanted. (Because you’re doing something with SOAP Attachements or other WSE niceties).

Anyhow, you can solve this problem by right-clicking on the web reference in the Solution Explorer, and selecting “Update Web Reference”, which will respect both the WSE2 and the URL Behavior. Just remember to do this after you select dynamic, otherwise you code blows up all over the place.

More on “Debugging in .NET COM classes running in the SOC… “

Posted by Dave Bouwman | Posted in ArcGIS Server | Posted on 12-08-2005

4

“KG” left some comments on my last post on this topic, and I was going to reply in the comments, but I scrapped that for a whole new post.

KG’s questions:

1. Is it as simple as wrapping existing code with the COM wrappers? Do I need to be concerned with any changes of code? Like creatObject or things like that?

I would not say you simply “wrap” your current ArcGIS Server client classes into COM classes. You need to think about how to break apart your code to optimize the use of SOC side processing. You don’t really want to move everything over there. My approach has been to built utility classes exposing methods to do the low level “dirty work” involving tight loops over sets of features. I then make calls to these methods from the “client” classes (running in a web service in my case).

One issue I’m having problems with is passing non-simple or non-ArcObjects types across to the object running on the SOC – I always get serialization errors on the method call. In one case, I was trying to send a System.XmlDocument across, and it threw the same error, which really suprised me. In this case, I ended up sending the XML across as a string, and it worked. I’ve gotten around this issue for now, but I’m going to look into this a little more, as it really impacts options for creating a nice OOP design.
If anyone has this working smoothly, I’d love to hear about it – it could well be that I’m just doing something wrong. I will note that I did try creating the class I wanted to pass across as a COM class, marked up the same was as the SOC classes, and I still goe the error.

I’d also suggest that you read the stuff in Chapter 4 of the ArcGIS Server Developer book so you get the correct attributes on your class, and implement the interface etc etc. If you follow that (or the samples), you should be fine.

Correct – when converting code to run in the SOC, you need to drop all your ServerContext.CreateObject(”foo”) statements, and just create an instance of the class like you would for normal ArcObjects. Another thing to keep in mind is that you don’t need to manage lifetimes when running in the SOC, so rip out any webObject.ManageLifetime and/or Using statements. Put them in the calling code, and manage the lifetime of your SOC class.

This brings up something that I’ve been puzzling on – “the zen of object lifetime managment”.

How and where do you manage lifetime of the SOC objects you instantiate? If you have a pretty simple model, like the samples, where you have one block of code that makes simple calls into AGS for data/map etc, it’s pretty simple – manage everything right there, and call webObject.dispose at the end.

But what if you have helper classes that deal with common tasks? I’ve found that if I try to manage lifetime (within the method itself) of objects instantiated in these methods, then the objects (or pointers to objects) returned from the method are really pointing to “nothing” after webObject.dispose is called. So what’s the best plan here? I have not worked this out yet, but one idea is to pass a webObject into the methods, have it manage lifetime on the objects you create in the function , and call dispose all at once when you’re done the outermost function and releasing the context.

As noted, I have not tried this yet (I don’t want to change all my method signatures until I know this is a good way to do it). What’s odd is that I see no difference if I explicitly manage the lifetimes or not. Granted that at this point, I’m only exercising my classes through NUnit, but I’ve got my server object setup to have only one instance, and I can re-run my test blocks as many times as I want, and there does not appear to be anything hanging around in memory (at least memory usage of the SOC process does not ratchet up). Maybe this only shows up when you run a heavy load? Anyhow – this is something that I’m going to more reseach on. Of course anyone with insights please let me know (Andy? Jithen? Brian?) :-)

2. So no VB6 is required huh? That would be great. I was looking into writing VB6 COM classes to run on the server but if I can use C# that would be better.

Yes – it’s much nicer to stick with the same environment for the entire project, and the debugging is pretty nice through .NET (not that I’ve tried DCOM debugging in VB6!)

3. How do you physically get the COM class over to the SOC from the dev machine? You mentioned that your dev box is the SOC but if it were not how would the move and reference take place

For development, make sure you’re working on the same box, or it will be a huge pain. For deployment, you need to put the dll’s on the SOC machine, and register them with COM. I have not done this yet, but I think you use regasm.exe(?). One thing that is a pain though is that you need to restart your server objects in order to recompile the assembly containing the SOC classes – ok, you only need to do this when debugging, after you have ungracefully exited the code, and left the SOC with pointers to your classes. I’ve also found that Visual Studio can spontaneously combust when trying to debug a process. Not sure why, but it restarts, and then works for a while longer. You’ll also need to stop the server objects when updating the dll’s on the server. This is very similar to using COM dll’s with classic ASP – start and stop IIS for each recompile.

Unit Testing and ArcGIS Server

Posted by Dave Bouwman | Posted in ArcGIS Server | Posted on 10-08-2005

0

Just a quick note on using NUnit for testing classes working with ArcGIS Server. I had setup my testfixture so that it would get a server context in the <SetUp()> sub, and release it in the <TextFixtureTearDown()> sub. This is generally good form – get an expensive resource one, and use it for all the tests…

<SetUp()> _
Public Sub Init()
‘Set up the connection to the GIS Server
    _SC = ServerUtil.GetMapServerContext(_AGSHostName, _AGSContextName)
End Sub

<TestFixtureTearDown()> _
Public Sub TearDown()
    _SC.ReleaseContext()

End Sub

And this works fine if you only run one test at a time, or if you only have one test in your test harness class. However, if you want to run a bunch of tests, you need to release the context at the end of each test, and thus also create it at the beginning. Simple enough, but somewhat confusing to see that you suddenly have 4 instances running when you only thought you had one.

Debugging in .NET COM classes running in the SOC…

Posted by Dave Bouwman | Posted in ArcGIS Server | Posted on 10-08-2005

3

Thought I’d write this down – mainly because I’ll forget how to do it the next time I have an ArcGIS server project, and also for the benefit of anyone else out there trying this…

Following the ESRI UC, I decided to stuff most of my ArcObjects code into COM objects that will run on the SOC. For my project, this was really important because I had a lot of tight loops using ArcObjects (I’m extracting data from rasters to be used in reports), and performance was really poor when users selected a large area. Thus, I bravely created a few projects (this post describes them), added COM classes, and gamely wrote up a post about how nice it all was. Of course I posted that it was all great and grand before I actually tried to run it. Of course it would work – right?

I did get things working, after some help from Brian Flood, and some digging in the “Developer Guide Scenarios” section on “Extending the GIS Server”.

These are some of the problems I ran into:

1) Creating COM objects in VB.NET
I created COM objects in VB.NET, by adding a COM class, and slapping in the properties and methods I wanted. Sounds reasonable eh? Nope. When I did this, and then called

Dim selUtil As SelectionUtil = DirectCast(_SC.CreateObject(”Sanborn.Utilities.ArcGIS.Server.SOC.SelectionUtil”), SelectionUtil)

I would get errors that selUtil was nothing. After some head scratching, I took a look at the examples in Extending the Server. Low and behold, there’s some idiosycnracies in these “COM” objects.

If you just add a COM class to a project, you get something that looks like this…

_
Public Class TestComClass

However, when you look at the sample code, you see this…

Imports System.Runtime.InteropServices
Imports System.EnterpriseServices

Public Interface IVegUtilitiesVBNET
Function sumVegetationType(ByRef pVegClass As IFeatureClass, ByRef pPoint As IPoint, ByRef dDistance As Double, ByRef sSummaryFld As String) As IVegResultsVBNET
End Interface

True), ClassInterface(ClassInterfaceType.AutoDual)> _
Public Class clsVegUtils

Inherits ServicedComponent
Implements IVegUtilitiesVBNET

Brian Flood indicated that the use of an interface, and the attributes are related to DCOM, and inheritance from ServicedComponent has to do with threading. This is a limited explanation, but good enough for me for now. The critical thing is that you MUST define your COM classes for use in the SOC like this. A word for ESRI – write this up somewhere! The developer guide only reviews using VB6 to create COM classes to run on the SOC. I would suggest writing up a simple technical white paper on this.

[UPDATE 8-10-2005]
Andy MacDonald of ESRI pointed me to a section in Chapter 4 of the ArcGIS Server developer guide where it does lay out the details of how to build COM objects in .NET for use in the SOC. Unfortunately I jumped directly to the section in Chapter 7 where the book reviews extending the server, and the example there is in VB6. Thanks for the update Andy!

2) Debugging the SOC Classes
Once I had my COM objects being created in the SOC, of course I ran into problems, and needed to debug. I had hoped that since my SOC was also my development system, that VS.NET would just step into the code when it was fired. Nope. Luckily I mentioned this to Brian Flood in an email, and he explained how to attach to a process in VS.NET for debugging. Now, I’m sure lots of people have done this before, but somehow I’d escaped the need to do it, so here’s Brian’s explanation (from an email)…

Goto the Tools>Debug Processes menu item and look for the ArcSOC.exe in the list (depending on how you set up your AGS config, there may be several of them). Since you are testing the code from your VS compile, the register for interop stuff *should* point the CreateObject progid call at the current assembly and thus its debugging symbols (*.pdb file). Attach to the process. Pray.

That’s about it, now I actually have my util classes working, and am working on stringing them all together in some SOC classes that are particular to my project.

 

ArcGIS Server Utility Classes…

Posted by Dave Bouwman | Posted in Uncategorized | Posted on 09-08-2005

0

Over the last couple of days I’ve been re-arranging the classes in some ArcGIS Server projects to create some utility assemblies, and I thought I’dwrite up a quick post on what I’ve come up with…

Basically I’m looking at server development a little differently after the UC – I’m taking the advice of pushing most of the processing into the SOC seriously. Previously, I was just doing it all in the client (a web service in my case), and was beginning to see performance problems. Anyhow, as most developers, I’m lazy at heart, so if I’m going to write something, I assume I’ll need it again, and if it’s at all generic (or “general” to avoid confusion with the new .NET 2.0 treats), I slap it into utility classes. Woo.

Anyhow, my thinking so far it to have two general utility assemblies:

Sanborn.AGS.Utilities.ClientSide
This has things used on the “client side” of the picture. By “client side”, I mean “not in the SOC”.
This mainly has functions related to the server ( CreateContext(HostName, ContextName) as IServerContext ) and some Map related that return Layers based on their Dataset Name. Certainly not comprehensive, but it’s a start.

Sanborn.AGS.Utilities.SOC
This holds handy things best done in the SOC.
This currently has things related to geometries, selections, raster extraction and some geodatabase stuff.

I also have two more assemblies which contain the unit tests for these Utility assemblies. My previous habit was to follow the “zen” of Test Driven Design, and had my tests directly in my classes, but since these tests rely on specific contexts running on specific machines, I did not see the use of shipping them with my code.

Since something here needs to be specific to the client, I’ve got another assembly which holds the custom “SOC side” logic required by this project. And finally, I have the web service itself. Seems to be working pretty well, despite the profusion of projects!

More Thoughts on Google Earth…

Posted by Dave Bouwman | Posted in General | Posted on 06-08-2005

3

After my last post on Microsoft not needing an “Earth” or “globe”, I got to thinking a little more. My original thinking was that the Globe as a GIS data visualization tool is somewhat limited – really only of use for very large datasets (nation, continent scale or larger). As such, Microsoft is not missing much without one.

But, as a visualization tool for other inherently spatial data (my thinking was related to news stories), it’s a very compelling interface. So, just as I am jotting this down, I found that Stefan Geens (whose post on MS buying ESRI started this all off), posted a comment , indicating that this same concept was behind his belief that Microsoft needs a “globe”. Not that Microsoft needs enterprise GIS, but rather that a global information visualization construct may be the next “browser”. Well – that saved me some writing…

So, I wanted to check out how this is coming along, and ogleearth.com is a great place to start. I quickly found “GoogleGlobe Assistant”, an Earth add-in that pulls news feed stories from BBC & CNN among other things. While this is still pretty rough around the edges, it’s a very good starting point for a new information construct. I would love to see News.Google.com integrated into Earth. The ability to select categories of stories, or keywords, and have those things show up on the globe automatically would be amazing. And I don’t think it will be long before it’s a reality.

Damn! blog-time runs pretty qucik – apparently this has been around for a few days – here’s a link to a KMZ file that is a RSS connection for the Washington Post (more about this here…). It seems that I’m not the only one with this idea… This is a screen shot of it in action…

Besides being really cool, I hope this catches on so that more people have an expanded world view. As a Canadian living in the US, I’ve always found that international news on traditional media outlets is limited at best. When there is news from outside the US, its either in the context of a horrible tragedy (Tsumani / Earthquake / Famine), or it’s related to the US bombing / invading / threatening something. In either case, it’s a quick bit, and then back to the sensational crap of the moment (Jackson Trial, Paris Hilton etc). If the “globe” as an information construct takes off for news viewing, perhaps people may realize
a) that the world is a little bigger than they thought, and
b) that there is something else going on out there.

On Microsoft buying ESRI… my thoughts…

Posted by Dave Bouwman | Posted in General | Posted on 04-08-2005

1

I just read Stefan’s post on Microsoft buying ESRI in some attempt to “recover” from the blow of Google Earth (linked through James Fee’s Spatially Adjusted blog).

While I don’t have a ton of time to speculate on if Jack and Laura would/will sell to Bill & Co., I will throw this in there – I don’t think Microsoft needs it. Google has “Earth”. Cool. As far as anyone can tell, they have yet to figure out how to make money with it. The only cash Keyhole made was in their sale, and click-through advertising will have limits. Whoo hoo.

I figure it’s a loss leader type of thing that is mainly meant to bolster the Google(tm) brand. The infrastructure to keep “Earth” running is pricy, and the data is orders of magnitude more costly – even buying older archive data. Additionally, the cool factor will wear off – the more people use it, the more they realize the limits of satellite data – it gets stale very quickly. And even if Google had all the money it wanted, there simply is not enough satellite capacity to have the entire globe mapped a relatively high resolution (say 1 meter over cities, 15 meters over rural areas) every year. That said the Google/Microsoft/Yahoo charge into having global coverage will certainly help out the satellite & image processing industries.

On top of this, there are so few things which lend themselves to visualization on a global scale. Yes it would be cool to see some global scale scientific data up on Google Earth, but that’s what NASA’s WorldWind is for (check this out if you have not – very very cool).

So – what then do you use it for? Search for ALL pharmacies? Or maybe you just want to know where Abu Dhabi is (check it – there’s some good Digital Globe data there!) Anyhow….

So Google Earth is very cool. But to Microsoft, the most successful software company in the world, one simple 3D app, with little more than “wow factor” driving it’s use, is not a make or break issue. I would argue that Google Maps is a little different issue – yes it’s about the maps, but more than that, it’s about the Web 2.0/AJAX interaction model. On this front you see lots of Microsoft action – including the Atlas client side framework (more here). This needed to be addressed – partly because they’ve been doing AJAX for quite some time, and party because they needed to allow their developers to create highly interactive sites easily. As for the maps, Virtual Earth is coming along pretty nicely, and from what I hear, the API is also pretty good. And yes, they may suffer a little slower adoption in the “hacker” community for the simple reason that it’s “Microsoft”.

As for ESRI and Microsoft – from a software perspective, it would be a great match – ESRI’s ArcObjects is one of the biggest COM packages out there, and the integration with the rest of the MS product line is relatively good. Another upside could be that SQL Server may get a spatial data type (would someone please do this already!!). But really, I think that ESRI likes their independance too much to sell out. And in the end, what could Jack and Laura do with a few billion that they can’t with a couple hundred million?? And if you’ve seen one of Jack’s keynotes at the annual user conference, you know he is doing exactly what he wants to be doing with his life – so I’d be very suprised to see ESRI up for sale