Custom Configuration Example #2: Web.Config + VB.NET

Posted by Dave Bouwman | Posted in .NET, Software | Posted on 29-12-2006

1

[UPDATE: 12/29/06 - Stephan sent me a note re: my incorrect spelling of "choropleth". At this point, I don't have time to change the code and graphics in the post, so just ignore the "l".]

As promised in my last posting, here’s an example of creating a custom configuration section handler using VB.NET in an ASP.NET application (sample code is for VS2003).

In this example I needed to pull data from the config file to setup a chloropleth choropleth mapping tool. The information is pretty straight forward – what layers can be used, for each layer, what fields can be used, and what are the minimum and maximum values for those fields. The Xml is shown below…

<chloropleth>

    <layer name=Named Lakes>

      <field name=ACRES min=0 max=1000/>

      <field name=FOO min=0.0012 max=0.2/>

    </layer>

 

    <layer name=Parcels>

      <field name=Price min=10000 max=100000000 />

      <field name=SQFT min=1233 max=3848922/>

    </layer>

  </chloropleth>

The corresponding class model is shown below.

The ChloroplethConfig class holds an ArrayList (if this were done in 2.0 it would be a generic List<of>) of ChloroplethLayers, which in turn holds an ArrayList of ChloroplethFields. The handler reads the Xml and converts it into these classes. Different from the C# example, these classes have overloaded constructors which allow me to pass in the Xml node from the config file, and they parse themselves. This is a nice pattern in that it makes the IConfigurationSectionHandler.Create method short and sweet…

 Public Function Create(ByVal parent As Object, ByVal configContext As Object, ByVal node As XmlNode) As Object

       Dim config As ChloroplethConfig = New ChloroplethConfig

       config.LoadValues(node)

       Return config

 End Function

When you run the app, it simply loops over the collections and reports what it has loaded from the config file. Very simple, but a nice way to validate that you’re custom config handler is working.

Anyhow – I’m working on another post which will build on using Custom Configuration Sections to build plugin frameworks – but I’ll save that for another day.

Custom Configuration Section Handlers in C#

Posted by Dave Bouwman | Posted in .NET | Posted on 27-12-2006

0

Many times when creating applications, you’ll need to allow the application to be configured in the deployment environment. One really handy way to facilitate this configuration is via the App.config or Web.Config files.

Key/Value Pairs

The default config file usage is based on Key/Value pairs in the appsettings section. This is very commonly used to store database connection or other relatively simple data which can follow a key/value pattern. Since this is not the main point of this posting, here is a link to an OdeToCode.com article that has more information on the appSettings usage.

But there are many cases when this is not enough, and for that we need to create our own Configuration Sections, and handlers to read them. I’ve used this on a lot of projects, and since it’s a little complex, I’ve created a little demo project
which shows how all the parts work together.

Demo Project Scenario

The scenario for the demo project is an application which needs to know
information about some key data layers. The details are contrived, but I’ve used
something very similar on real applications, so it is pertinent. The application simply reads a custom configuration section, and shows the information in a text box.

.

Create the “Data” Classes

Unless you’re really comfortable with Xml, I’d suggest designing the classes
which will hold the configuration data you’ll be reading our of the App.Config
file. This way you’ll know what you need to store in the Xml. In my example, there is just one class – DataLayer, but it does contain a List of FieldNames (strings) and an Enum for the source of the layer.

Create the Configuration Section Xml

Once you have figured out what you want to get from the configuration file, the next step is to create the Xml that will store it. In my case, I’m going to have one or more DataLayer object, each with one or more fields. I’ve created the following Xml to represent this in the config file.

  <dataLayers>

    <layer name=Parcels source=ArcGISServer>

      <field name=PIN/>

      <field name=Owner/>

      <field name=Acres/>

      <field name=Price/>

    </layer>

    <layer name=Buildings source=ArcIMS>

      <field name=ParcelPIN/>

      <field name=Address/>

      <field name=SQFT/>

    </layer>

  </dataLayers>

Create the Section Handler

Now that we’ve added a new section to the App.Config file (dataLayers), we need to tell the .NET framework how to access it. To do this, we must create a class that implements IConfigurationSectionHandler, and register the section in the App.Config file. This is shown below but the type and assembly names have been simplified for readability.

  <configSections>

    <section name=dataLayers type=DaBo.ConfigHandlerDemo.DataLayerSectionHandler, DaBo.ConfigHandlerDemo  />

  </configSections>

The Section Handler class is simply used by the framework to read the section, and handle it however the developer wishes. The code below shows the implementation of the IConfigurationSectionHandler.Create method for the example.

        public object Create(object parent, object configContext, System.Xml.XmlNode section)

        {

            //Initialize the list of datalayers

            List<DataLayer> layers = new List<DataLayer>();           

            //Select the layer nodes

            foreach (XmlNode n in section.SelectNodes(“//layer”))

            {

                DataLayer dl = new DataLayer(n);

                layers.Add(dl);

            }          

            return layers;

        }

The Section Handler simply parses the passed in section node (dataLayers in the Xml), extracts out the layer nodes, passed them into the DataLayer constructor, and adds the DataLayer to a list of DataLayers which are returned to the calling code (shown below).

List<DataLayer> dataLayers = (List<DataLayer>)ConfigurationSettings.GetConfig(“dataLayers”);

For completeness sake, here’s the code in the DataLayer constructor.

 public DataLayer(XmlNode node)

        {

            _fieldNames = new List<string>();

            //Pull the layer name from the name attribute of the node

            _layerName = node.Attributes["name"].Value;

            //Parse the string into the enum

            _source = (DataLayerSourceEnum)Enum.Parse(typeof(DataLayerSourceEnum), node.Attributes["source"].Value, true);

            //Handle the fields

            foreach (XmlNode n in node.SelectNodes(“//field”))

            {

                //make sure this Field is a child of the current layer node

                if (n.ParentNode == node)

                {

                    _fieldNames.Add(n.Attributes["name"].Value);                  

                }

            }

        }

Here’s how it all works:

  1. ConfigurationSettings.GetConfig locates the section handler by name, in the config file.
  2. It creates an instance of the associated SectionHandler , DaBo.ConfigHandlerDemo.DataLayerSectionHandler in this case
  3. It passes the dataLayers node into the Create method on this class
  4. Which returns a list of DataLayer objects to the application.

This is a really great way to add all sorts of configuration into your applications. Since you control all aspects of what’s stored in the Xml, and how it’s returned to the application, you can do anything you want. This technique works exactly the same way for web applications, and I’ll post up a simple Web.Config demo app that’s written in VB.

Download the Sample code (.NET 2.0 C#)

“Meme”-y Christmas: Five Things You Don’t Know About Me…

Posted by Dave Bouwman | Posted in Blogging, Life | Posted on 24-12-2006

2

Steve of the Sacramento Citron-Pousty’s tagged me for this little
disclosure.

 
1) While programming, I really like to crank trance / techno music. Can’t
stand it any other time, but I’ve got a big pile of Paul Oakenfold etc. for hammering out
code. Go figure…

2) Despite being a life long geek (I had a Commodore
PET
way back in the day), I somehow also got into skateboarding. Apparently I was
pretty good, as I was sponsored by a local skateshop (or maybe there were not
many skaters). Being as I lived in Ottawa, Canada, and skateboarding was not
socially acceptable at that time, there were very few skate ramps. The one time
I did get on a big ramp (16 footer), I slammed and busted my nose.

3) I am a chill/ambient music junkie (maybe this transcends from the techno
thing?). Ambient Nights is a great
free collection if you’ve not checked this out before. Reminds me of chillin on
a beach in Thailand, sippin Mai Tai’s.

4) When I started at COGS (wow that’s a podunk web
site for a very good school!), my plan was to go work for ESRI in Redlands. HOwever, the plan changed when I met (now my wife) Jill, and thus we
are in Fort Collins.

5) Despite egging on every American I know to get out and vote, I have not
voted in a Canadian election in 10+ years. Maybe it’s because I figure that if
the most extreme lunatic gets elected there, they will have little net negative
effect on the world. As we have seen, this is not the case in America. 

Apparently I get to pass this on. Who’s up? How about Art Haddad, Brian Flood, and Glenn Letham.

Fort Collins Snowday!

Posted by Dave Bouwman | Posted in Life | Posted on 21-12-2006

2

Not sure who get’s to officially “call” a snowday, but I’ve got 2 feet of snow outside my garage door, and an alley with 3 foot drifts in it, so I’m not going anywhere today! Here are some pics…

View off my front porch in Old Town Fort Collins…


This is my neighbors SUV – buried.

Happy Holidays!

MySpace.com runs ASP.NET

Posted by Dave Bouwman | Posted in .NET, ASP.NET, Team System | Posted on 17-12-2006

0

While we all know that Microsoft/Live/MSN etc are all running on ASP.NET, I was just reading a post on Paul Wilson’s blog, which referred to an earlier post by Scott Guthrie (for those who don’t know, he’s General Manager in Microsoft’s Developer Division) that says MySpace is also running on ASP.NET 2.0.

Here’s a quote regarding scalability (circa March 2006)…

  • MySpace.com is now processing 1.5 Billion page views per day
  • MySpace.com handles 2.3 million concurrent users during the day
  • MySpace.coms average server CPU utilization went from 85% to 27% after moving (from another technology) to ASP.NET 2.0

Since then, MySpace has apparently surpassed Yahoo! in daily page views. In the comments on Paul’s post, we find more interesting news…

One other nice-to-know: They’re actually developing with Visual Studio Team System on top of Team Foundation Server. Not a big deal, but when you consider their all-up continuous integration solution, it definitely speaks to the power and capability of the VSTS/TFS combo.

As a developer working with Microsoft tools, it’s nice to hear about these sorts of things. Now if I could just cook up a site as popular as MySpace… ;-)

Clarifications on ArcGIS Server Licensing

Posted by Dave Bouwman | Posted in ArcGIS Server, ArcSDE | Posted on 15-12-2006

0

James has posted a “quick hits” rundown of ESRI’s white paper on ArcGIS Server licensing, and upgrades for existing users. Give his post and the document a read if you’ve been trying to sort this stuff out.

I’m not going to say that there was a cause-effect relationship between my previous post on this topic, and the ensuing comment thread (96 comments as of today) over at James Fee’s blog, but at least these questions have been clarified for the entire user community.

Mobile ADF: A First Look…

Posted by Dave Bouwman | Posted in ArcGIS Server, Mobile ADF | Posted on 11-12-2006

0

This weekend I lugged my EDN disks home, installed server, and played around with
the Mobile ADF.  While the SmartPhone and PocketPC options are interesting, I’ve
tried to do complex data entry on small form factor devices, and Tablet
PC’s are simply a better platform for this type of work. Adding in a Map and GPS makes for some really cool possibilities.

Quick Summary: 

The Mobile
ADF
 may be one of the most compelling (and undersold) reasons to get the Advanced
Server. Really.

Why?

First off, it’s dead easy to use. Drag and drop a few things, and you’ve got
a simple application. The sample apps are good (C# only – not sure if VB.NET
versions are in the works), and cover a range of topics, and includes templates for common use cases. Another nice touch is that the
samples come with pre-baked MapCaches, so you can start working with them without setting
up a Mobile MapService. The API also has some very interesting capabilities which leave openings for some more advanced functionality – such as feature level permissioning and complex topological validation.

Next, unlike the bulk of ArcObjects, the Mobile ADF is native .NET, which is
nice because you can write classes without getting COM in the mix, and it means you can use xcopy deployments. The only downside is that you can’t reuse classes
from ArcMap/Engine in this ADF, but I don’t see that as a really big issue.

Additionally, the ADF provides implementations of various ADO.NET
classes & interfaces for interacting with data in the MapCache. 

This means that developers who are used to the ADO.NET paradigm can easily
adopt the Mobile ADF without learning a whole new data access methodology (i.e. the
ESRI.ArcGIS.Geodatabase
namespace). By building on the ADO.NET framework, they have enabled direct databinding (sample included!) Can you say “rapid
development”?

Final Thoughts (for now)

Smart Client technology is and will continue to change how applications are written and used. And more so that just mobility – the concept of local data caches, updated at the end of a session is becomming more pervasive – even when a connection is available. I see a lot of really cool uses for the Mobile ADF into an Enterprise system.

A broader question is “Will the Mobile ADF become the new MapObjects?” It’s light-weight, native
.NET programming model, ability to read/write from the enterprise Geodatabase
(via Advanced Server), support for DataBinding, and smart client capabilities
make it a compelling alternative. The per-seat cost is low, and apparently you get 50 seats with Advanced Server (thought I saw this online, but can’t find the link again!).

Another possible MapObjects parallel could be that this represents the first steps of a platform migration – this time from COM to .NET. Is this first
step towards a simplified, COM-free ArcObjects API? Thoughts?

Single vs Multiple Database ArcSDE

Posted by Dave Bouwman | Posted in ArcSDE | Posted on 10-12-2006

1

Ron Bruder & Derek Swingley pointed out that I had misunderstood the Single vs Multiple database thing, and the relationship to SDE vs DBO owned schema.

Since I missed this, and I’ve been using SDE since before they attached “Arc” to the front of it, I’m guessing some other people may have missed this as well (or like me, skipped reading the 9.2 documentation!).

My Logic (Wrong!)
I has assumed that the “single” and “multiple” were referring to the SDE system table repository.  Thus,  the “Single” database model  was  the traditional model where the system table repository was in one database – “SDE”.  Additionally, I had assumed that “multiple” referred to  storing the table repository in multiple databased.  This is completely backwards.

How it REALLY works

Ron posted a link to a Forum posting by Derek, in which Derek posted a link to the explanation of this on the ArcSDE  on-line docs.  Since pictures are worth a 1000 words, I’ve linked the diagrams from that site here  (disclosure: these are ESRI diagrams, hosted @ EDN.)

Single Database Model

This is the “default” and recommended model at 9.2.


Multiple Database Model

This is the traditional model with the SDE table repository in the SDE database.

SDE & DBO schema
You can use either SDE or DBO schema with both “single” and “multiple”. Derek also provided a link to web help on this topic.

Thanks for getting me on the right track with this!

Loading Personal Geodatabases into ArcSDE

Posted by Dave Bouwman | Posted in ArcSDE | Posted on 08-12-2006

3

Ran into a problem loading data from a Personal Geodatabase, and thought I’d share the solution.

Scenario:
Data was coming from ArcSDE on Oracle, exported to a PGDB, and then I’m importing it into ArcSDE on SQL. We had to go this route because Xml Workspace export threw errors.

Error Message:
The error effectively says that the field length exceeds the maximum for a datatype.

After some digging around, I figured out the problem:

  1. The string field in a layer in ArcSDE on Oracle has a length of 2000
  2. During the export to Personal Geodatabase, this field becomes a “memo” because a string field in access has a max length of 254.
  3. When re-importing into ArcSDE, Catalog interprets the length of the field as 2147483647, which is too big, and the import fails.

The question is – how can I get this data back into ArcSDE?

Solution:

  1. Export the schema for the layer as Xml
  2. Edit the Xml and change the field length back to 2000
  3. Create the featureclass from the Xml
  4. Use the Object Loader to transfer features from the layer in the PGDB into ArcSDE.

ArcSDE 9.2 Setup Notes

Posted by Dave Bouwman | Posted in ArcSDE | Posted on 08-12-2006

4

I needed to investigate the various setup options for
using ArcSDE 9.2 with SQL Server 2005. These are condensed notes that I made while checking things out and setting up a few instances.

SDE Setup Options

There are really three sets of questions which you need to think about when
setting up ArcSDE 9.2:

  • where will the SDE schema tables reside?
  • how will the users connect?
  • how will users be authenticated?

SDE Schema Location

For the last few releases (possibly since 9.0?), you could setup SDE in two
ways – with the SDE schema, or “stand-alone” databases. At 9.2, this is up
front and a choice during the post-install, and they are formally named  “dbo-schema” or “sde-schema”.  This is
really referring to the location of the sde_* and gdb_* tables which hold the
“sde metadata” (i.e. domains, metadata, relationship definitions etc).

DBO Schema

In this option, all the SDE repository
information is stored in the target database. You need to run the post-install
for each spatial database you want to create. If you use ”dbo-schema” with SDE
services, you will need a separate service for each database – which is somewhat
more complex to setup, but should be workable once you get
layerfiles/templates setup. I see this setup as a better option if you are using direct
connect. In that scenario, there are no extra services to setup, and since everything required for your spatial database in one place, you only have to backup\restore that one database – which really helps if you store a lot of static data in ArcSDE (i.e. rasters)

SDE Schema

This is the traditional model where the SDE schema information is in a
separate SDE database. The only downside to this model is managing a mix of static and dynamic databases. In order to keep all your backups in synch, you need to back up the SDE database, as well as all of the databases containing spatial data. That said, this is certainly workable, as this is how most users have things setup.

Connection Type

As with 9.1, there are two connection types: SDE Service or Direct
Connection. With the SDE service connection, the client connects to a running
process on the ArcSDE server (giomgr.exe), which communicates with the database.
Using Direct Connect, there is no running “SDE” process on the database server,
and the client handles the details of interacting with the tables. Although direct connect was slower in previous releases, ESRI has done a lot of work to reduce the network “chatter”, so the
performance is close to being on-par with the SDE Service.

The really big upside of direct connect is the off-loading of the “SDE” work to the client. On a fully loaded SDE Server, approximately 1/2 of the load is the ArcSDE process (according to the ESRI System Architecture document & class). By moving this load to the client, the database server can handle almost twice the number of connections. When I heard this, my initial thought was – “that just makes the client slower”. While this is true to some extent, as a percentage of the entire transaction, the SDE communcations is just a tiny percent as comparte to the rest of the client (ArcMap for example) Another way to put it is that the load gets big on the SDE box because it’s the focal point for a lot of little processes from all the clients. Re-distributing that load out to the clients has little noticable impact, and your database scales way better. Which is good because DBMS licensing is not cheap.

It’s worth noting that while Direct Connect has many upsides,  it does add
complexity to upgrades. The version of the client dlls (installed with
Desktop/IMS/Server etc) must exactly match ArcSDE. Thus, to do any upgrade you
must upgrade all the software at once. As I understand it (and I’m still waiting
for confirmation of this) this includes service packs. Conversely, if you use an
ArcSDE service, this acts as a version proxy between the client and the
underlying database, and thus you have more flexibility with mixing
software versions when deploying an updated. Just something to keep in mind when
designing your system.

Database Authentication vs Windows Authentication

Regardless of how you have setup the schema or the connection, you can now
use either Windows or Database authentication. Windows Authentication is
convenient in that you do not need to create additional logins in the database,
and you can assign privileges to groups of Windows Logins from within ArcCatalog
- thus simplifying the database managment.

Quick note on Performance…

In my experience, direct connect seemed slower during the inital connecting
to the spatial database. Once connected, there was no noticable difference. Not sure if this is a function of my setup (I set up
ArcSDE to use services, then I stopped the service and specified direct connect
in ArcCatalog), but connections via ArcSDE were almost instant. Both were using
Windows Authentication. My suggestion is to try it out and see what works best
for you.