Zero Touch and the Cache

I had a chance to travel to Calgary earlier this week to speak at the Microsoft Bigger Better Basic conference.  One of the session I was scheduled for including a number of demos on the Smart Client technology.  So I'm sitting on the plane running through the demos just to make sure that I don't...er...mess up in front of 600 people and I get to the Zero Touch Deployment (ZTD) demo.  This is a straightforward demo showing what happens if you move a .NET application onto a virtual directory.  The deployment is done by clicking on a link in a simple HTML page.  So sweat right?

So I get to the part where the HTML page is displayed, click on the link and...nothing happens.  That strikes me as a little strange, so I start checking on the normal stuff.  Does the file exists.  Is it really a .NET application.  Does the link in the HTML page point to the right place.  All looks good.  So now I go on to the more esoteric possibilities.  Do I have the appropriate permissions defined in the Framework Configuration Wizard.  Are there any settings in the virtual directory that might be giving me grief.  Has ASP.NET been installed in the virtual directory.  Still nothing.

Now I'm beginning to pull my hair out.  After another 15 minutes or so of puzzling, I try to view the source for the HTML page.  Nothing happens.  Fortunately, this is a situation that I'm familiar with.  If you can't view the source for a web page, your temporary Internet cache is full.  And then it hits me.  No room in the Internet cache means that the downloaded application doesn't have a place to live.  So I go into the Internet Options, clear out my cache and ZTD works like it's supposed to.  No damage (other than those haris that are still stuck between my fingers).

But this does bring out one of the biggest weaknesses in the ZTD model.  The downloaded application lives in the cache, along with other pages of stuff from the Internet.  It is too easy for a user to clear out the cache, thus removing the benefit of off-line functionality.  I believe that this situation will be corrected one of the future products (I can't remember whether it's Indigo, Whidbey or Longhorn).  The correction is the cache the ZTD applications in a different location and allowing a generally more granular level of cache clearing.  Can't come too soon for my taste.  ZTD is nice, but when in the hands of the uninitiated, it has the potential to generate some help desk traffic.

ASP.NET and the Event Log

Today's tidbit revolves around enabling the ASP.NET user to generate entries into the event log.  In an ideal world (hint, hint Microsoft designers), this would be a relatively straightforward process.  Or at least one that didn't require a direct hack into the registry.  But that is not the case at the moment.  So without further ado, here are the steps involved in enabling the ASP.NET user to create event log entries.

1. Launch RegEdit
2. Navigate to HKEY_LOCAL_MACHINE\SYSTEM\
    CurrentControlSet\Services\EventLog\
3. From the menu, select Edit->Permissions
4. Click the Add button and write ASPNET.  (if ASP.NET is running under a different user id, use that id instead)
5. Click OK.
6. Select the newly added user from the list (ASP.NET Machine User by default).
7. Click on Full Control in the Allow column.
8. Click OK.

It is usually a good idea at this point to restart IIS with the IISReset command (Start | Run | IISReset).

For those concerned with the security hole that has been opened up.  Once these changes are implemented, the ASP.NET user has full control over the Application event log.  Worst case scenario, a bad process could fill up the event log or delete existing log entries.  However, as far as security breaches go, these are fairly minor, especially when compared to the benefits of being able to view log entries.

IsNumeric Best Practices

Needing to find out what the best why to implement the IsNumeric function in C# is, I went on a brief tour of the Internet today.  My result is a very informative article by J. Ambrose Little that benchmarks six (count 'em, six) different techniques.  The result is a virtual tie between an incremental character technique (use the Char.IsNumeric method on each character in a string), the Double.TryParse and VisualBasic.IsNumeric.  Useful information to keep in mind in the future.

Phantom Properties

Yet one more interesting Web Service problem reared its head today.  The situation is as follows:

The result of a call to a Web Service method is supposed to be a class. The class contains the elements that, basically, make up a record in a database table.  Because of the way that we structure data access, our data access class returns a DataSet with a matching xsd file.  Once the xsd file had been created, the xsd.exe tool was used to create the class definition.  An instance of the class was then hydrated using the XML format of the DataSet and returned through the web service.

(just for the curious amongst you, our reason for not returning the DataSet itself is that the client is an older version of WebSphere and they don't have easy support for processing returning DataSets.)

Key point coming:  the minOccurs value on at least some of the data elements in the xsd was set to 0.  As a result, for some of the data types (specifically integers, int16 and bytes), additional properties were created.  For example, if there were a property called Status, a public boolean property called StatusSpecified would also be created. 

No problem to this point.  A web method is created with a return value of the class that was generated by xsd.  The method is called and *bam* (picture Emeril at this point), an error gets generated.  The error is the following:

Server was unable to process request. File or assembly name q2k5rmkd.dll, or one of its dependencies, was not found.

The experienced among you will recognize this as a error that occurs when the ASP.NET user doesn't have access to the temporary directory.  But that was not the case here. It is also an error that gets returned when one of the classes used in a web service message has a ReadOnly property.  But a review of the returned class shows that this is not the case either. 

As it turns out, the problem is that the Specified properties (such as StatusSpecified) conflicts with an automatically generated property called, coincidentally, StatusSpecified.  This automatic property is generated when the result set contains a minOccurs clause.  It is used with numeric values to identify those properties that have not been assigned.  It is necessary because numeric variables don't have a 'null' value. But the conflict between the autogen'ed properties and the properties that are created by xsd causes the error message seen above.  The easiest solution is to change the name of the properties included in the xsd.exe generated class to have a name that does not have 'Specified' as the suffix.

Interoperating with WebSphere

I just had the joy of spending a day trying to get my .NET Web Service to interact with a WebSphere client.  Regardless of the changes made, the following error was received on the Java side.

Unable to retrieve PropertyDescriptor for property Xxx

All of the property names matched up.  All of the properties in the Java class had getters and setters. The ultimate solution?  Change the case of the property names.  The problem only occurred if the property name started with a capital letter.  If changed to a camel case format, the problem goes away.  Apparently, this is a problem with the standard BeanSerializer in older versions of WebSphere (version 5.0 and earlier).  According to the notes that I found, it has been corrected at 5.1 and in a patch to 5.0.  Can't vouch for this, as we just swallowed hard and changed the case of our exposed properties.  I hate case sensitivity.

Getting Started

Since this is the first entry in my first weblog, I feel the need to describe what readers (or potential subscribers) can expect.  First, my background is an interesting combination of technical and marketing.  I have spent most of the last twenty years working in the technology field, covering everything from DOS to UNIX to Windows and now .NET. In my current incarnation, I have been developing both Web and Windows applications using the .NET Framework.  However along with my technical side comes some communication skills.  At least, I like to think they've come along.

I have been writing for technical publications and speaking at anyplace that would have me for most of the last decade.  This experience allowed me to find what I call my 'voice'.  As anyone who has both read and heard me will attest, the two styles are not that different.  In other words, I write like I talk.  And I talk in a stream of consciousness. So be ready for topics that can go all over the map.

Now that the introduction is out of the way, let me describe what the blog will contain.  In the course of my work, I get a chance to work with Web Services in the real world.  While much of the theory and standards are interesting, the sometimes get in the way of actually making Web Services do what we need them to do.  This blog is dedicated to discussing Web Services where the petal meets the metal.  I'll be discussion the quirks of creating Web Services and getting them to interoperate with other non-Microsoft environments.  I'll look at how to go about creating an infrastructure that supports Web Services at the enterprise level.  This includes both security and instrumentation.  I think that this mandate (the one that I'm giving myself, that is) should allow for a wide range of commentary.  And I'll try to keep the posts as regular as my work allows.