“无法加载App_Web _ * .dll”ASP.NET编译后的异常&回收

时间:2010-10-29 11:55:42

标签: asp.net wcf iis

我最近遇到了以下结构的代码:

  • FooService.cs
  • FooService.svc
  • Default.aspx

文件内容:

[FooService.cs]

using System.ServiceModel;

namespace FooService
{
    [ServiceContract]
    public class FooService
    {
        static FooEngine engine = new FooEngine();

        [OperationContract]
        public string Foo()
        {
            return "bar";
        }
    }

    public class FooEngine
    {

    }
}

[FooService.svc]

<%@ ServiceHost Language="C#" Service="FooService.FooService" %>

[Default.aspx]

<%@ Page Language="C#" %>
<% var foo = "bar"; %>

我们在Windows Server 2003上使用.Net 4.0(调试)和IIS6,并使用'fooservice'网站和主机文件条目通过http://fooservice/FooService.svcdefault.aspx通过{{3}调用Web服务}}。在这一点上,一切都很完美。

但是,经过以下步骤后,

  1. 更改default.aspx中的代码,保存文件
  2. 加载http://fooservice/(触发ASP.NET编译)
  3. 回收应用程序池
  4. http://fooservice/的调用失败并引发以下异常

    [FileNotFoundException: Could not load file or assembly 'App_Web_ynlv0b1k, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.]
       System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0
       System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +39
       System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks) +132
       System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +144
       System.Reflection.Assembly.Load(String assemblyString) +28
       System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) +208
       System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath) +1440
       System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +44
       System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +615
    
    [ServiceActivationException: The service '/FooService.svc' cannot be activated due to an exception during compilation.  The exception message is: Could not load file or assembly 'App_Web_ynlv0b1k, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified..]
       System.Runtime.AsyncResult.End(IAsyncResult result) +679246
       System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +190
       System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication context, String routeServiceVirtualPath, Boolean flowContext, Boolean ensureWFService) +234
       System.ServiceModel.Activation.HttpModule.ProcessRequest(Object sender, EventArgs e) +355
       System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
    

    这到底发生了什么?

    说明

    • 我了解ASP.NET正在编译并加载新的App_Web_*.dll(在第2步中),但为什么在回收后尝试加载旧的(已删除的)App_Web_*.dll(3) ?
    • FooService.svc中使用完全相同的内联代码而不是单独的FooService.cs没有此问题(?)
    • 删除对FooEngine的静态引用也会导致此问题消失(?)

7 个答案:

答案 0 :(得分:19)

我刚遇到同样的问题, 该应用程序是一个Web应用程序,因此完全预编译。 这为我修好了,但我不确定原因:

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

我从这里得到了这个解决方案:http://web.archive.org/web/20140116171941/http://www.creative-jar.com/insights/labs/programming/could-not-load-file-or-assembly-app_web_/

答案 1 :(得分:3)

它必须是编译器问题,如前所述。如果您无法访问iis,则可以修改自己的web.config文件以使用其他临时目录。这个修改将使iis重新编译你的代码并使用这个新的编译。

<compilation tempDirectory="C:\...">

iis_iusrs用户必须具有对此新目录的写访问权。

答案 2 :(得分:2)

代码不应该是以下结构:

  • FooService.cs
  • FooService.svc
  • Default.aspx的

但是以下内容:

  • App_Code文件 /FooService.cs
  • FooService.svc
  • Default.aspx的

请注意包含源代码的特殊App_Code文件夹。

所以回顾一下:

~/App_Code/FooService.cs

using System.ServiceModel;

namespace FooService
{
    [ServiceContract]
    public class FooService
    {
        static FooEngine engine = new FooEngine();

        [OperationContract]
        public string Foo()
        {
            return "bar";
        }
    }

    public class FooEngine
    {

    }
}

~/FooService.svc

<%@ ServiceHost Language="C#" Debug="true" Service="FooService.FooService" CodeBehind="~/App_Code/FooService.cs" %>

~/Web.config

<configuration>
  <system.web>
    <compilation debug="false" targetFramework="4.0" />
  </system.web>

  <system.webServer>
     <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>

~/Default.aspx

<%@ Page Language="C#" %>
<% var foo = "bar"; %>

据说我建议您使用Web Applications instead of Web Sites并预编译所有内容以避免出现这类问题。另一个优点是您不再需要在服务器上部署源代码。

如果您使用经过编译的Web应用程序,您的结构将如下所示:

  • 仓/ MyWebService.dll
  • FooService.svc
  • Default.aspx的

这是我建议你的。

答案 3 :(得分:0)

我们已经看到,在某些情况下,应用程序回收从未实际执行过。我在负载很重的大型网站上看过这个。 IIS使用非常积极的缓存机制,并且根据请求队列长度实际上不会强制完全循环。

如果您看到这一点,请尝试执行IISRESET /noforce。这应该告诉服务器真正真正回收所有东西。

答案 4 :(得分:0)

您可以将IIS应用程序池设置为在特定时间段或某些应用程序失败时回收。请查看以下可能对您有用的网址:

http://forums.asp.net/p/1551597/3934757.aspx http://weblogs.asp.net/albertpascual/archive/2010/07/01/installing-asp-net-4-in-iis-6.aspx

Gaurav Maniar MCP | MCSE | MCST | MCITP | ITILv3认证

答案 5 :(得分:0)

这似乎是Asp.Net编译器的一个问题。它似乎没有为重新编译时使用新的DLL构建更新WCF的临时ASP.NET文件。你能否请用batch = false测试应用程序,即&lt; compilation batch =“false”&gt;

答案 6 :(得分:0)

我的项目遇到了类似问题,网站工作正常,但任何svc webservices都出现了同样的错误。

我尝试在web.config中更改下面的行,但这没有帮助

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

我发现的解决方案与应用程序的构建方式有关。

当我使用部署项目时,我发现取消选中该选项:

  

视为库组件(删除App_Code.compiled文件)

<输出程序集'页面中的

,然后重建和部署项目似乎对我有用。

希望能帮助别人。