Posts
33
Comments
106
Trackbacks
0
May 2008 Entries
TFS 2008 - Delete a Team Project and the "You are not authorized to access <machine>." message

After an oops with creating a team project in TFS 2008 with an incorrect name, I wanted to cleanup by removing the team project with the incorrect name.  However, someone else created the project and every time I tried to delete the team project using the tfsdeleteproject.exe command line tool, I got the error message:

"You are not authorized to access <machine>."

Uhhh, what?  I'm a domain admin in this domain.  How can this be?

After fumbling around a bit, I had a hunch and checked permissions on the TFS Team Project.  Sure enough, I had permissions on the TFS project, but I had no access to the Sharepoint site or the Reporting services reports.  After using the TFS Admin tool to grant myself permissions to these resources, I was able to delete the Team Project successfully.  The tool was failing to verify I had permissions to these; it would have been helpful to get this feedback rather than the generic "you are not allowed to access this server" message.

Posted On Friday, May 23, 2008 9:15 AM | Comments (3)
Enterprise Library 3.1 - Different Configuration Sources Across Blocks

I recently had a co-worker inquire about using different configuration sources across different application blocks within the Enterprise Library.  As has already been demonstrated (both in the EntLib documentation and on various websites), it's extremely simple to modify the source of configuration information for the entire Enterprise Library.  This is provided both by the EntLib framework and the configuration tool.  Simple create a new/alternate Configuration Source, set it as the default configuration source, and away you go.  You can use one of the out-of-the-box configuration sources (alternate file source, e.g.) or write your own (put configuration in Sql, a flat file, registry, or whatever you can conjure up).

However, splitting configuration between different application blocks is slightly different.  It's not truly natively supported by EntLib, but the pieces needed to achieve this are present in the framework, and the customization required to pull it off is extremely straightforward.

To demonstrate, I'll pull configuration for a single application block from a separate configuration file.  In theory, and as I described earlier, this can be from any source for which a ConfigurationSource provider exists.

First, create your EntLib configuration.  In my case, I've got the Data Application Block and Caching Application Block defined/configured.  I've also created an alternate config source entity called 'Cache Configuration Source'.  It points to another file called separateconfig.config.

entlib.configuration entlib.configuration.properties

Now, the default configuration source is still the System Configuration Source, which is the application's configuration file (application.exe.config).  However, I've also created a separate configuration file called separateconfig.config that I want to pull Cache Application Block configuration data from.  What I'll do is copy the configuration (including the configSection declaration) from app.config to separateconfig.config for the caching application block:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:   <configSections>
   4:     <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
   5:   </configSections>
   6:   <cachingConfiguration defaultCacheManager="Cache Manager">
   7:     <cacheManagers>
   8:       <add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000"
   9:           numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"
  10:           name="Cache Manager" />
  11:     </cacheManagers>
  12:     <backingStores>
  13:       <add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
  14:           name="Null Storage" />
  15:     </backingStores>
  16:   </cachingConfiguration>
  17: </configuration>

You can remove this corresponding configuration from the original app.config, although this has implications on configuring this data in the future (more on this later).  Now we have to figure out how to pull this configuration when instantiating the CacheManager from the EntLib.  The default CacheFactory simply uses the default configuration source (our app.config file) to pull configuration.

   1: // native EntLib functionality
   2: return CacheFactory.GetCacheManager();

Under the hood, however, what's going on is that the CacheManagerFactory is being passed the default ConfigurationSource and instantiating the CacheManager from that configuration.  If we can override the ConfigurationSource being used, then we're golden.  Luckily, the lower-level CacheManagerFactory class allows us to do just that.  So, we simply create our own implementation of the CacheFactory class and return a singleton, as follows:

   1: // only needed if we are overriding the default CacheFactory singleton
   2: private static CacheManager cacheManager = null;
   3: private static object lockObject = new object();
   4: // only needed....
   5:  
   6: private static CacheManager GetCacheManager()
   7: {
   8:  
   9:     // Custom behavior -- use a different config source
  10:     // In order to provide this, we don't use the default CacheFactory behavior; we create our own.
  11:  
  12:     if (cacheManager == null)
  13:     {
  14:         lock (lockObject)
  15:         {
  16:             if (cacheManager == null)
  17:             {
  18:                 // Create a custom configuration source
  19:                 IConfigurationSource cacheSource = ConfigurationSourceFactory.Create("Cache Configuration Source");
  20:                 CacheManagerFactory managerFactory = new CacheManagerFactory(cacheSource);
  21:  
  22:                 cacheManager = managerFactory.CreateDefault();
  23:             }
  24:         }
  25:     }
  26:  
  27:     return cacheManager;
  28:  
  29: }
  30:  

As you can see in the code snippet, the Configuration being used to construct a CacheManager is from the "Cache Configuration Source" configuration source that we defined in the system configuration (the app.config).  In short, we're pulling from separateconfig.config to construct the CacheManager class.

Pulling this configuration from a separate location has an implication on design-time configuration.  Natively, the configuration tool can't persist configuration to different locations at the same time (it simply writes to the default configuration source).  I suppose you could investigate modifying the configuration tool to support this functionality, but I haven't explored this myself.  I have also seen community-developed tools that will allow you to specify a configuration section and use an alternate ConfigurationSource provider to persist the configuration to an alternate location, but this would always by a manual post-configuration deployment task.  In the end, how you achieved this would depend on the effort required to customize the tools or your workflow and the cost associated with the manual effort of persisting the configuration where it ultimately needed to go.

Posted On Friday, May 23, 2008 8:52 AM | Comments (0)
WCF Client Endpoint Contract Changes Between VS2005 and VS2008

As I noted earlier, I recently converted a Visual Studio 2005 solution with WCF clients to Visual Studio 2008.  After making some additional changes and running the application, I started getting errors instantiating the WCF clients.  The message -- that the contract for my WCF client couldn't be found in the list of endpoints in my config -- was unexpected since I re-created my WCF clients with the same name (and in the same namespace) as before.

After a quick inquiry with my colleague (and brilliant WCF programmer, I might add) David Pallmann, he pointed me to the ConfigurationName property of the ServiceContract attribute.

Sure enough, VS2005 (via svcutil.exe) appeared to generate ConfigurationName values that matched the entire interface typename (Namespace1.Namespace2.Etc.ServiceClass.Interface).  However, VS 2008 appears to shorten this to only include the class and interface (ServiceClass.Interface).  Without referring to the svcutil.exe documentation, I'm guessing you can provide this value, and the WCF tools bundled with VS 2008 must be shortening the name.

I updated my config files, and the WCF clients worked again (having found the matching endpoint configurations now).  Not a big deal, although I'm again disturbed that the upgrade to VS2008 required code changes.

What I find really interesting is that the ConfigurationName property of the ServiceContract attribute seems to map to the endpoint Contract value in the config.  Shouldn't the value of Contract be the type of the contract we're implementing for this client, and not necessarily configurable?  Seems like a misnomer to me.  What's also unusual, IMHO, is that the ConfigurationName property of the ServiceContract attribute doesn't map to the Name property of the client endpoint.  Weird.

Listening to: idobi Radio

Posted On Friday, May 9, 2008 3:32 PM | Comments (0)
WCF and Debug vs. Release Builds

(This post should also be sub-titled: Development Back to Basics)

I was working on a WCF project the other day, trying to resolve some minor behavior anomalies.  As I often do, I made some code changes, re-compiled, and de-deployed binaries to IIS6, where this particular WCF service was being hosted.

Having done this numerous times in the past, I was quite surprised to see a ServiceActivationException:  "The Service Type could not be found... yadda yadda."  Uhhh, what?  It's right there!

Scenario:  Me, Visual Studio 2005 running on Windows Server 2003.  Deployed:  Clean, production-quality Windows Server 2003, .net 2.0 & .net 3.0.  That's it.

I start digging.  Somewhere along the way, I come under the suspicion that dependent assemblies are missing, so I use the most excellent Process Monitor to monitor w3wp.exe for file load failures.  (Later, I learn that I think I could have used the Fusion Log Viewer, but Process Monitor worked in this case regardless).  I find something interesting:

The w3wp.exe fails to load two dependent assemblies: VJSharpCodeProvider, and CPPCodeProvider.

Question:  "Why is my assembly trying to load code providers for J# and C++ when I have clearly written it in C#?"

I racked my brain as to what could have changed in my solution to cause it to be referencing these assemblies.  I mean, I checked EVERYTHING, and came up with nada.

After staring at the IDE for literally hours (ok, maybe not continuously), I glanced at the build configuration.  The word 'Debug' stared back at me.  Could it be?

I recompiled as Release, re-deployed, and voilá!   It worked!

As many years as I've been compiling code, you'd think I wouldn't make a silly mistake like this, but it just goes to show you that it's always a good refresher to to get back to basics.

Posted On Thursday, May 8, 2008 3:48 PM | Comments (0)
Updating WCF Clients (created in Visual Studio 2005) in Visual Studio 2008

I recently updated a Visual Studio 2005 project with WCF service references to Visual Studio 2008.  After some interface updates, I needed to update the service references.  After some rummaging around for the 'Update Service Reference' context menu and spending some time googling the scenario, I finally realized that the organization and implementation of WCF client handling via the Visual Studio 2005 extensions is different than that in Visual Studio 2008.  The result?

You have to re-generate any service references for you to be able to continue to update/edit in Visual Studio 2008.

Fantastic!

Posted On Thursday, May 8, 2008 3:22 PM | Comments (5)
Comment and opinions are my own and do not reflect on my company in any way.
Tag Cloud