Friday, January 15, 2010

Need to Avoid ASP.Net web.config Inheritance?

I ran across a situation yesterday where ASP.Net web.config inheritance bit me in a way that wasn’t pleasurable.  Here is my situation.
I have 2 ASP.Net web applications on a single IIS web site, 1 ASP.Net web app and 1 WCF web services.  For example:
IIS Setting Virtual Path Comments
www.MyWepApp.com \MyWebApp This is my 2.0 ASP.Net web application
www.MyWebApp.Com\MyServices\ \MyWebApp\MyServices This is my 3.5 WCF web services

As you can see, I have a hierarchy going on where “MyServices” is an IIS web application under the IIS web site (also an IIS web app) “MyWebApp” and “MyServices” is a sub-directory under “MyWebApp.”  Since we have a web application at the IIS web site root (“MyWebApp”) and that site has a web.config, ASP.Net inheritance kicks in for any web applications that are “children” to “MyWebApp.”
So the error message I was getting was that I already had a <sectionGroup> defined for “System.Web.WebExtensions" when I tried to invoke a web service under “MyServices.”  Sure enough, If I looked at both web.config’s the <configSections> were duplicated.  After some searching I found you can do two things to avoid these conflicts.  (1) Make sure the <confiSections> point to the same assembly versions and (2) add a <location> element to your root web.config and set it to not allow child inheritance.
So let’s look at (1) – Making sure the <configSections> match.  Here is the config section from the web app:
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>

Here is the section from my web services:
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>

Notice the differences in the Version numbers of the assemblies.  The Web app had references to the 1.0 assemblies and the web services had references to the 3.5 assemblies.  Because of ASP.Net inheritance, whenever I tried to consume a web service it tried to “re-write” the same config sections because they have the same name but different values.  Updating the <configSection> of the web app to match the web services (all pointing to the 3.5 assemblies allowed me to work.  This is because the <configSections> that have the same name in both web.configs now have the same value.

For (2) adding the <location> element to the root web.config here is the line I added:

</configSections>
<location inheritInChildApplications="false">
<system.web>

There are a couple of things to note here.  (1) the <location> element must be after the <configSections> and before the <system.web>  If you have <appSettings> or any thing else those must also be outside the <location> element.

(2) the “inheritInChildApplications” attribute is not defined in the asp.net web.config schema which is why it has a red underline.  That is ok.  Apparently Microsoft added this to the asp.net engine but not to the schema.  Whatever it works.

(3) because of note (1) and the fact that <location> wraps the <system.web> section, all other sections are using asp.net inheritance, which is why we have to deal with (1) and the same version of the <sectionGroups> assemblies anyhow.

Thursday, January 14, 2010

Expertise Persona Exercise

I’m in a codemash session with Mary Poppendieck on Competency and Leadership and we are doing an exercise on creating a persona on how your company hires and thinks of expertise. The exercise is this. Create a persona for a new hire coming into your group / company. Here are the facts:

  • Person is 1 year out of college
  • Person has a technical degree and is hired into a technical role (tester, developer, etc)

Describe how the following is accomplished for this person:

  • How does this person get their work assignments and from who?
  • How does this person improve their competency in the position they were hired for?
  • Who gives this person feedback on their performance and competency and how often?
  • How does this person learn about the “customer” they ultimately serve?

The point of the exercise is to think about how you and your group think about competency. Do you value the fact that people should be skilled in technical positions and how concerned are you about continual improvement for that skill? How does feedback help? How often should feedback occur? How do you value mentorship and are the “right” people giving feedback? Meaning, do you get feedback from someone who doesn’t have the technical background to perform the job? If so, how does that individual know what is wrong / right and ultimately grow in that skill?

It was a very interesting exercise given the wide range of experience in the audience. I’m still in the session and still processing it but one thing I know for sure, netflix sure sounds like a cool place to work. :)

Don’t be a tool

Values lead to practices that determine tools.

VALUES –> PRACTICES –> TOOLS

So I’m sitting in the first pre-compiler session at CodeMash 2010.  I’m actually late to it (surprise) but the session is End-To-End Coaching Software Developer teams.  The first thing I see is the following phrase:

VALUES lead to PRACTICES that DETERMINE tools.

I couldn’t agree more.

The presenter talked about how it is so common in our industry for it to work in the exact opposite manner.  How often do we see a vendor SELL a tool, a dev shop buys the tool and then what happens.  A GUIDANCE team is formed on HOW BEST TO USE A TOOL.  So in this paradigm, the shop follows this pattern:

TOOLS DICTATE GUIDEANCE that management need to ENFORCE best practices.

What happens to VALUES in that model?  What happens is that VALUES are not even thought of.  There isn’t room for VALUES in that model.

So what if one of your VALUES is simplicity?  It doesn’t matter because the TOOL dictates whatever it wants, regardless of complexity.

The presenter talked about how this is a detriment in terms of money to the company.  I can see that.  VALUES can lead to practices to save money and achieve great quality.  All this without the letting a tool dictate the exact opposite.

A fresh start

Well, I started my blog about 5 months ago with all the best intentions and probably how most blogs end up… it didn’t last.  I created 2 posts and just stopped.

Now to be fair, I’m a regular blogger inside of my company’s internal blog infrastructure, I just never know whether people outside my company’s walls will care about any of this.  I guess I should wonder if people inside of my company’s walls care too…

At any rate, here I am again, wanting to give it another go.  I’m attending the CodeMash 2010 conference and I’m feeling inspired again.  And besides, I secretly made a new year’s resolution to be more active in the software development community at large and part of that commitment is to blog more.  (Yes, I realize that this is almost as common as a new year’s resolution to loose weight but what are you going to do… I made one of those too. :)

So my fresh start will take place in the form of using blogger.  I realized that hosting my own blog site was crazy and wanted to use one of the services available.  I have my domain switched over, the pre-compiler day for CodeMash 2010 has come to an end and I’m ready to share my musings with the world.  I hope you enjoy.

Thanks -- Ed