Asp.net 分析器错误:无法加载类型";x";来自IIS7中虚拟目录中的appdomain
所以我的场景有点滑稽,但这是有原因的 我有一个名为parent的父web应用程序和另一个名为Child的web应用程序。子目录是IIS7中父目录下的虚拟目录,父目录是IIS中的应用程序。Child不是文件系统中父目录的子目录,仅在IIS中作为虚拟目录。在父web应用程序中加载应用程序(application_Start in global.asax)时,我告诉它使用Assembly.LoadFrom()将子web DLL从childs bin文件夹加载到父web应用程序的应用程序域中。然后,当我尝试访问/Child/Default.aspx时,我会收到一个错误,上面写着: 分析器错误 分析器错误消息:无法加载类型“Child.\u Default” 现在Child.dll(包含childs code behind等的web dll)位于父应用程序的应用程序域中,我可以在父页面Default.aspx中成功地从code behind中反映它及其成员 此外,在Child/Default.aspx上,如果我将Inherits=“Child.\u Default”更改为Inherits=“System.Web.UI.Page”,然后在页面上的标记中枚举应用程序域中的dll,我可以看到Child.dll并反映其成员和调用函数Asp.net 分析器错误:无法加载类型";x";来自IIS7中虚拟目录中的appdomain,asp.net,iis-7,appdomain,Asp.net,Iis 7,Appdomain,所以我的场景有点滑稽,但这是有原因的 我有一个名为parent的父web应用程序和另一个名为Child的web应用程序。子目录是IIS7中父目录下的虚拟目录,父目录是IIS中的应用程序。Child不是文件系统中父目录的子目录,仅在IIS中作为虚拟目录。在父web应用程序中加载应用程序(application_Start in global.asax)时,我告诉它使用Assembly.LoadFrom()将子web DLL从childs bin文件夹加载到父web应用程序的应用程序域中。然后,当我
一个有效的方法是在page指令中将CodeBehind更改为CodeFile。然后页面将正确解析。但是,这仅在网站处于未编译、未发布的状态时有效。当appdomain尝试解析子项目中页面的“子”程序集时,它没有在其程序集列表中查找 您需要做的是在AppDomain中使用AssemblyResolve事件处理程序。您可以这样做:
<system.web>
<compilation>
<assemblies>
<add assembly="Child"/>
</assemblies>
</compilation>
</system.web>
首先,我们创建并组装Loader类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using System.IO;
namespace Parent
{
internal class AssemblyLoader
{
private static List<AssemblyInformation> virtualDirectoryAssemblies = new List<AssemblyInformation>();
private static readonly string virtualDirectoryBinFolderFormatString = "~/{0}/bin/";
private static readonly string[] pathSplitParams = new string[1] { "\\" };
private static readonly string[] assemblyNameSplitParams = new string[1] { "," };
internal static Assembly AssemblyResolve(object sender, ResolveEventArgs e)
{
var name = e.Name.Split(assemblyNameSplitParams, StringSplitOptions.RemoveEmptyEntries).First();
if (!virtualDirectoryAssemblies.Exists(a => a.Name.Equals(name)))
return null;
return Assembly.LoadFrom(virtualDirectoryAssemblies.Single(a => a.Name.Equals(name)).Path);
}
internal static void LoadVirtualDirectories(List<string> virtualDirectories)
{
foreach (var v in virtualDirectories)
{
var path = HttpContext.Current.Server.MapPath(string.Format(virtualDirectoryBinFolderFormatString, v));
AppDomain.CurrentDomain.AppendPrivatePath(path);
AppDomain.CurrentDomain.SetShadowCopyPath(path);
var assemblies = Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories).ToList();
foreach (var a in assemblies)
{
var name = a.Split(pathSplitParams, StringSplitOptions.RemoveEmptyEntries).Last().Replace(".dll", string.Empty);
if(!virtualDirectoryAssemblies.Exists(i => i.Name.Equals(name)))
{
virtualDirectoryAssemblies.Add(new AssemblyInformation
{
Name = name,
Path = a
});
}
}
}
}
class AssemblyInformation
{
public string Name { get;set; }
public string Path { get; set; }
}
}
}
我们完成了…:P
<system.web>
<compilation>
<assemblies>
<add assembly="Child, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</assemblies>
</compilation>
</system.web>
<system.web>
<compilation>
<assemblies>
<add assembly="Child"/>
</assemblies>
</compilation>
</system.web>
protected void Application_Start(object sender, EventArgs e)
{
AppDomain.CurrentDomain.AssemblyResolve += AssemblyLoader.AssemblyResolve;
var virtualDirectories =
ConfigurationManager.AppSettings.Get("VirtualDirectories").Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
AssemblyLoader.LoadVirtualDirectories(virtualDirectories);
}