Issue deploying WCF service to IIS 6 in non-updateable mode
I have been working for the last week trying to get to the point where I could reproduce an error. The scenario is actually very simple. All I want to do is be able to deploy WCF services using the ASP.NET pre-compilation non-updateable model where the implementation is separated from the web application project (to help facilitate unit testing). Ok maybe it isn’t that simple J
I am working with VS.NET 2008 and .NET 3.0. I have been able to isolate this down to an issue with deploying to a Win 2K3 server in IIS 6 using specifically a virtual directory to host the application root. When I use a new web site in IIS 6 it works fine but as soon as I move the binaries over to a virtual directory I get a “Value cannot be null. Parameter name: key” error coming from the System.ServiceModel.Activation.MetabaseSettingsIis.GetTransportSettings(String VirtualPath). It appears to be attempting to lookup the settings in a dictionary during activation and it can’t seem to find anything for the virtual path being sent in (again … only when I’m in non-updateable mode).
Also, as soon as I deploy using the updateable mode (where the .svc file gets markup) it works fine. I have screenshots, trace files, and repro steps that I can send if you are able and willing to help. Any and all ideas are appreciated.
Answers
I ended up solving this issue (after numerous attempts to hack the .compile files and significant grinding of teeth), it turns out the whole “Publish Web Site” deployment model within VS.NET 2008 hinges on the name of the web application project directly mapping to the virtual directory name. I had been doing some manual hacks to the .compile file to make it work in the default web site which was essentially giving me a false positive. Now it works just fine everwhere (IIS 6 / IIS 7) as long as I make sure the customString attribute maps to the IIS virt-dir. Of course, this does mean these files are not very portable. If you want to move them from one virt-dir to another then you’ll need to manually change the bolded portion of the customString below or you’ll see that error I have listed below.
For example:
I have a virtual directory (web application in IIS 7) under a website called “WCFTest”. If your web application project is named WCFTest you’re fine but if it isn’t you’ll need to go in and update it manually (or setup a custom build script that changes the settings in the aspnet_compiler). Here’s what my Service.svc.compile file looks like that works (the key portion is in bold).
<preserve resultType="5" virtualPath="/WCFTest/Services/Service.svc" hash="55fe3ce3" filehash="38d428ec94f6" flags="110001" customString="/WCFTest/Services/Service.svc||ServiceImplementation.Service|System.EnterpriseServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|ServiceImplementation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null|System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|System.IdentityModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|ServiceImplementation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<filedeps>
<filedep name="/WCFTest/Services/Service.svc" />
</filedeps>
</preserve>
Also worth mentioning is a bit of a headache when doing a precompile on a box that has .NET 3.5 installed. The issue is with all those assemblies you see in the customString. If you’ve installed .NET 3.5 you’ll have System.WorkflowServices 3.5 and System.ServiceModel.Web 3.5 in the list which blows up when you deploy to a box that only has .NET 3.0 installed. Obviously the targeting feature in VS.NET 2008 does not ensure that invalid assemblies end up included in the aspnet_compiler operation. All you have to do to fix this is go into the %system drive%\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config and remove the previously mentioned assemblies from the list in the <assemblies> node.
All Replies
I ended up solving this issue (after numerous attempts to hack the .compile files and significant grinding of teeth), it turns out the whole “Publish Web Site” deployment model within VS.NET 2008 hinges on the name of the web application project directly mapping to the virtual directory name. I had been doing some manual hacks to the .compile file to make it work in the default web site which was essentially giving me a false positive. Now it works just fine everwhere (IIS 6 / IIS 7) as long as I make sure the customString attribute maps to the IIS virt-dir. Of course, this does mean these files are not very portable. If you want to move them from one virt-dir to another then you’ll need to manually change the bolded portion of the customString below or you’ll see that error I have listed below.
For example:
I have a virtual directory (web application in IIS 7) under a website called “WCFTest”. If your web application project is named WCFTest you’re fine but if it isn’t you’ll need to go in and update it manually (or setup a custom build script that changes the settings in the aspnet_compiler). Here’s what my Service.svc.compile file looks like that works (the key portion is in bold).
<preserve resultType="5" virtualPath="/WCFTest/Services/Service.svc" hash="55fe3ce3" filehash="38d428ec94f6" flags="110001" customString="/WCFTest/Services/Service.svc||ServiceImplementation.Service|System.EnterpriseServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|ServiceImplementation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null|System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|System.IdentityModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a|ServiceImplementation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<filedeps>
<filedep name="/WCFTest/Services/Service.svc" />
</filedeps>
</preserve>
Also worth mentioning is a bit of a headache when doing a precompile on a box that has .NET 3.5 installed. The issue is with all those assemblies you see in the customString. If you’ve installed .NET 3.5 you’ll have System.WorkflowServices 3.5 and System.ServiceModel.Web 3.5 in the list which blows up when you deploy to a box that only has .NET 3.0 installed. Obviously the targeting feature in VS.NET 2008 does not ensure that invalid assemblies end up included in the aspnet_compiler operation. All you have to do to fix this is go into the %system drive%\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config and remove the previously mentioned assemblies from the list in the <assemblies> node.
"...the whole “Publish Web Site” deployment model within VS.NET 2008 hinges on the name of the web application project directly mapping to the virtual directory name."
You Sir, are a Legend.
I have wasted > 4hrs trying to work out what the *** I was doing wrong with publishing my Web Service Host.
I've been playing with the Service Factory Modelling Edition and the recommended naming of the host project (in the accompanying walk thru) was "xxx.scm.svc.wcf.Host" which I decided to follow, but I was using the VS2008 publish wizard specifying an IIS virtual web of just "xxx" when deploying to a different server. As soon as I read your post and published it as "xxx.scm.svc.wcf.Host", all my problems went away.
*sigh*, that little point might have been beneficial to add to the walk through notes or VS help... maybe it is in there somewhere, but I didn't see it.
Thanks again,
Kev.
- Thanks Tom Fuller,
You saved a lot of time for me too.
I have solved the problem by doing as you suggested on local IIS.
Now i am facing a problem while hosting it on Godady . I get an xml error saying :
-----
XML Parsing Error: no element found
Location: http://mydomain.com/myWCFService.svc
Line Number 1, Column 1:
-----
any idea what could be wrong sir ?
ShadowMan : The Lord of Dead Side - Hello Tom
Can you please help me out on this Issue.
I am getting this error when I am trying to browse my service .svc file after the installation on the server.
I got this error
Could not load file or assembly 'Microsoft.ServiceModel.Channels, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
FileNotFoundException: Could not load file or assembly 'Microsoft.ServiceModel.Channels, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.] System.RuntimeTypeHandle._GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName) +0 System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +64 System.RuntimeType.PrivateGetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +58 System.Type.GetType(String typeName, Boolean throwOnError) +59 System.ServiceModel.Configuration.BindingsSection.UpdateBindingSections() +240 System.ServiceModel.Configuration.BindingsSection.get_Properties() +19 System.Configuration.ConfigurationElement.Reset(ConfigurationElement parentElement) +38 System.Configuration.RuntimeConfigurationFactory.CreateSectionImpl(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader) +128 System.Configuration.RuntimeConfigurationFactory.CreateSectionWithFullTrust(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader) +50 System.Configuration.RuntimeConfigurationFactory.CreateSection(Boolean inputIsTrusted, RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader) +38 System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader) +69 System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line) +67 [ConfigurationErrorsException: An error occurred creating the configuration section handler for system.serviceModel/bindings: Could not load file or assembly 'Microsoft.ServiceModel.Channels, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.] System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult) +202 System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject) +1061 System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) +1431 System.Configuration.BaseConfigurationRecord.GetSection(String configKey, Boolean getLkg, Boolean checkPermission) +56 System.Configuration.BaseConfigurationRecord.GetSection(String configKey) +8 System.Web.Configuration.HttpConfigurationSystem.GetSection(String sectionName, VirtualPath path) +55 System.Web.Configuration.WebConfigurationManager.GetSection(String sectionName, String path) +58 System.ServiceModel.Configuration.ConfigurationHelpers.UnsafeGetSectionFromWebConfigurationManager(String sectionPath, String virtualPath) +37 System.ServiceModel.Configuration.ConfigurationHelpers.UnsafeGetAssociatedSection(ContextInformation evalContext, String sectionPath) +154 System.ServiceModel.Configuration.ServicesSection.UnsafeGetSection() +25 System.ServiceModel.Description.ConfigLoader.LookupService(String serviceConfigurationName) +16 System.ServiceModel.ServiceHostBase.LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, String configurationName) +24 System.ServiceModel.ServiceHostBase.ApplyConfiguration() +69 System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses) +190 System.ServiceModel.ServiceHost.InitializeDescription(Type serviceType, UriSchemeKeyedCollection baseAddresses) +32 System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses) +139 System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(Type serviceType, Uri[] baseAddresses) +28 System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) +331 System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath) +11656092 System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +42 System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +479
Can you please help me in this all Issue
Thanks In advance
Takecare Bye
Swapnil S A better solution would be to use "~" instead of the virtual path. I've tested this and it works just fine. For the previous example, the .compile file would then have the following content:
<preserve resultType="5" virtualPath="/WCFTest/Services/Service.svc" hash="55fe3ce3" filehash="38d428ec94f6" flags="110001" customString="~/Services/Service.svc||ServiceImplementation.Service|System.EnterpriseServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b...
This can become a custom build step in TFS with a grep like utility that does the search & replace.- Proposed As Answer byincola Monday, August 31, 2009 12:49 PM
Readers of this thread may want to know about the following related threads:
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/ce57bf0e-74a1-492f-aca6-69597edf1a39
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=367241
great_scandinavianLast night I had the 'Value cannot be null. Parameter name: key' error for hours and hours. Last thing I changed were the NTFS permissions on disk. From the root of the disk I added the NETWORK SERVICE, ASPNET and IUSR_<compname> accounts with default permissions. Then went to bed, this morning it works.
I had an WCF 3.5 service, hosted in IIS 6 on Windows Server 2003 Std. The service is being called from an ASP.NET web application (.NET 3.5). I used the http://wcfextras.codeplex.com/ extension to use SOAP headers.


