I have previously explained how to properly configure your web deployment projects to replace web.config sections. The example I used was pretty standard – swap out connection strings to support the specific deployment environment. It worked great, right? Well, today this technique complete fell short for me as I was dealing with a custom section.
We recently introduced NServiceBus message sending into our ASP.NET MVC 2 web application. It’s working so well I can hardly believe it. Anyway, we put a two configSections in place for the NServiceBus:
- <configSections>
- <section name="MsmqTransportConfig"
- type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core"></section>
- <section name="UnicastBusConfig"
- type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core"></section>
- </configSections>
- <!– NServiceBus –>
- <MsmqTransportConfig InputQueue="SendingEndpointQueue"
- ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5"></MsmqTransportConfig>
- <UnicastBusConfig>
- <MessageEndpointMappings>
- <add Messages="Project.Messages" Endpoint="ReceivingEndpointQueue"></add>
- </MessageEndpointMappings>
- </UnicastBusConfig>
When I attempted to replace these settings, the WDP threw the following build exception:
An error occurred creating the configuration section handler for MsmqTransportConfig: Could not load file or assembly NServiceBus.Core’ or one of its dependencies. The system cannot find the file specified.
I tried a number of workarounds, but I wasn’t able to resolve the issue. In the end, I abandoned the WebConfigReplacement technique and started replacing the entire the web.config file using an ExcludeFromBuild command…
- <ItemGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
- <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\obj\**\*.*" />
- <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\.svn\**\*.*" />
- <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\.svn\**\*" />
- <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.csproj" />
- <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.user" />
- <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\bin\*.pdb" />
- <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\Notes.txt" />
- <!– WebConfigReplacement validates configSection references before
- replacement and NServiceBus.Core or dependencies could not be found.
- Now we are excluding web.config from build as it will be
- manually replaced in BeforeBuild step. –>
- <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\web.config" />
- </ItemGroup>
…and a BeforeBuild Copy task…
- <Target Name="BeforeBuild">
- <Copy SourceFiles="$(SourceWebPhysicalPath)\Config\Web.Int.config"
- DestinationFiles="$(CopyBeforeBuildTargetPath)\web.config" />
- </Target>
This approach considerably reduced the number of configuration files which I need to manage. And it works too. I’m not saying you should change your approach, but be aware of the potential issue if you start to implement custom configuration sections.
Note: I’ve read that the WebConfigReplacement technique will only work for types which have been installed in the GAC. I added NServiceBus.dll and NServiceBus.Core.dll to the GAC and that didn’t make much difference. Perhaps NServiceBus.Core dependencies are the culprit? I also read that some folks have implemented their own msbuild task to do a simple text replacement of the configSource property to solve this problem. The configSource property isn’t made available by NServiceBus and I didn’t go ahead and add it.Lazy me. Last thought: I tried many things but flipping the <ValidateWebConfigReplacement> switch to false would fix everything. It didn’t.
You can tell NServiceBus to get its configuration from a different source by including .CustomConfigurationSource(yourSource) in the fluent initialization code. Maybe that’ll sort things out for you.
Thank you for the pointer, Udi. And thanks for NServiceBus. It’s amazing!
Fantastic blog! Do you have any recommendations for aspiring writers? I’m hoping to start my own blog soon but I’m a little lost on everything. Would you suggest starting with a free platform like WordPress or go for a paid option? There are so many options out there that I’m totally confused .. Any suggestions? Appreciate it!