我在两个独立的Web应用程序之间创建一个具有完全独立代码库的接口,因此我可以重用另一个应用程序中的逻辑。我通过在父应用程序中创建第二个AppDomain来加载第二个Web应用程序,并使用代理在两者之间进行通信。
这是有效的,但前提是我使用特定的应用程序池,特别是如果我使用内置的.NET 4.5 Classic'应用程序池。如果我使用手动创建的应用程序池,则会收到错误'无法映射路径' / App_GlobalResources /'。
问题是,我无法看到应用程序池当前配置方式之间存在任何实际差异。我也不认为这是一个权限问题,因为即使我在同一个管理员帐户下运行这两个应用池,这仍然会发生。
这是来自applicationHost.config的应用程序池的XML:
<add name=".NET v4.5 Classic" managedRuntimeVersion="v4.0" managedPipelineMode="Classic">
<processModel identityType="SpecificUser" userName="{my username}" password="{my encoded password}" />
</add>
以下是应用程序池的XML,它不起作用:
<add name="{app pool name, removed as it contains the client name}" managedRuntimeVersion="v4.0" managedPipelineMode="Classic">
<processModel identityType="SpecificUser" userName="{my username}" password="{my encoded password}" />
</add>
这是应用池的默认设置,即使我认为这不会有所作为:
<applicationPoolDefaults managedRuntimeVersion="v4.0">
<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="false" />
</applicationPoolDefaults>
在应用程序池配置方面有什么我缺失的吗?或者我应该配置和/或调查的任何其他内容?
EDIT 2014/07/08:
这是一个重现问题的自包含示例:
https://drive.google.com/file/d/0B7mtq3lFmDqyd1VZZ1ZCdHFsa1U/edit?usp=sharing
要进行此设置,您必须将WebApplication1设置为localhost / WebApplication1,将WebApplication4设置为localhost / WebApplication4。
您还应该将Default.aspx.cs中的硬编码路径更改为指向计算机上WebApplciation4的根目录。
您可能需要尝试使用几个不同的应用池来重现错误。我建议在经典模式下为.NET 4设置一个新的。
EDIT 2014/07/12
这里是错误的堆栈跟踪:
[InvalidOperationException: Failed to map the path '/Mvc/App_GlobalResources/'.]
System.Web.Configuration.ProcessHostConfigUtils.MapPathActual(String siteName, VirtualPath path) +244
System.Web.Configuration.ProcessHostServerConfig.System.Web.Configuration.IServerConfig.MapPath(IApplicationHost appHost, VirtualPath path) +34
System.Web.Hosting.MapPathBasedVirtualPathEnumerator..ctor(VirtualPath virtualPath, RequestedEntryType requestedEntryType) +285
System.Web.Hosting.MapPathBasedVirtualPathCollection.System.Collections.IEnumerable.GetEnumerator() +43
System.Web.Compilation.CodeDirectoryCompiler.ProcessDirectoryRecursive(VirtualDirectory vdir, Boolean topLevel) +321
System.Web.Compilation.CodeDirectoryCompiler.GetCodeDirectoryAssembly(VirtualPath virtualDir, CodeDirectoryType dirType, String assemblyName, StringSet excludedSubdirectories, Boolean isDirectoryAllowed) +670
System.Web.Compilation.BuildManager.CompileCodeDirectory(VirtualPath virtualDir, CodeDirectoryType dirType, String assemblyName, StringSet excludedSubdirectories) +175
System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled() +508
答案 0 :(得分:0)
事实证明,应用程序池错误是一个轻微的红色鲱鱼,因为任何应用程序池都没有真正正常工作但只有一个错误。
通过ApplicationHost.CreateApplicationHost
创建新的应用程序主机时,框架将使用SimpleApplicationHost
而不是ISAPIApplicationHost
,这通常在IIS中托管网站时使用。 SimpleApplicationHost
非常简单,并将网站名称默认为默认网站&#39;您可能会注意到这些值与IIS中的默认网站相匹配,这意味着当一个应用程序池似乎正常工作时,它实际上是将其路径映射到默认网站,这意味着虚拟路径正在解析绝对路径,如C:\ inetpub \ wwwroot \ Mvc \ App_GlobalResources&#39;,无论如何都不正确。
修复方法是将VirtualPathProvider
从默认MapPathBasedVirtualPathProvider
更改为自定义提供程序,该提供程序根据子应用程序的已知值进行映射。事实上我已经这样做了,但是我在这个过程中做得太晚了,因为在新应用程序主机的初始化期间抛出了错误,这是ApplicationHost.CreateHost
调用的一部分。在这一点上似乎所有希望都失去了......
然后,我发现了ASP.NET的一些鲜为人知的功能PreApplicationStartMethodAttribute
。这实际上是由BuildManager
使用的ASP.NET ApplicationHost.CreateHost
的初始化使用的。通过实现此属性,我可以在初始化代码使用之前替换虚拟路径提供程序。
我实际上并没有发现一个应用程序池似乎工作而另一个应用程序池没有用的原因,但我怀疑它是webengine4.dll中的并发问题,还是一个问题网站名称被传递到WebEngine4.dll。