Search code examples
asp.netvb.netwcfassembliesprecompiled

WCF service in a precompiled web application - Could not load file or assembly


I have a solution which contains multiple WAPs (Web Application projects).
Every WAP has it's own Web Deploy project in order to be able to precompile these sites. On one of the web app we are created a new WCF file with

AspNetCompatibilityRequirementsMode.Allowed

In debug mode it is working ok, but if i switch to release it crashes:
(we are using msbuild to create the deployable versions)

Could not load file or assembly 'App_Web_*****, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

I found some explanation in this link: WCF service

WCF stores the list of referenced assemblies into the customString attribute in the build result (service.svc.cdcab7d2.compiled), including App_Global. It seems there is an incorrect assumption here that those assemblies will always be there, which is not necessarily the case in Web Deployment Projects (aspnet_merge) where assemblies will be merged. After the merge step, the assemblies are actually all merged into a single assembly (let us say MyWebSite.dll) as we selected that option in WDP. ASP.NET only updates the .compiled files it knows about, so App_Global.asax.compiled actually has a correct reference to MyWebSite_Deploy.dll instead of App_Global.dll. Original assemblies are removed after the merge step. WCF reads the list of assemblies previously stored, and throws when it cannot find App_Global

List of solutions i've tried:

1.Check 'Allow this precompiled site to be updatable' - not worked

2.Remove manualy the App_* reference from service.compile file
(It worked but it should be another solution)

3.Add fully qualified name for the service/factory in .svc
The service has a fully qualified name.

4.tried to set this key:
<SourceWebPhysicalPath>..\..\ProjectName</SourceWebPhysicalPath>

following these instructions

5.<compilation debug="false" batch="false">

Tried this to set to web.config using these instructions

6."Merge All outputs to a single assembly"
i haven't tried this because it requires to register all the used assemblies to GAC and means we need to change the deployment logic.

I don't want to delete the asp.net temporary folder because it stops the application and it is inacceptable

I also found Scott Gutthrie link but it's from '07 it should made it's way to asp.net 4.0

Additional Info

The service is placed:
ProjectName\WebResorce\Service.svc ,

<%@ ServiceHost ... Factory="SolutionName.SharedWeb.WadoLabsServiceHostFactory" %>

where the SharedWeb is a Shared Web project

Do you have any other ideas?
Thanks in advance


Solution

  • The following setup worked for me:

    1. In the svc file, specify a qualified name of the service, as <%@ ServiceHost ... Service="<Namespace>.<ServiceContractClass>, <AssemblyName>" CodeBehind="ServiceContractClass.svc.vb" %>
    2. (Can't remember why it was required, but) I made sure that the Namespace and the AssemblyName are different.

    The trick is to specify the qualified name, including the AsseblyName.(The assembly name that is specified in the project containing the service, not the Web Deploy Project).

    Also note that there is a space between the comma after the class name, and the AssemblyName.