Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 分析器错误:无法加载类型";x";来自IIS7中虚拟目录中的appdomain_Asp.net_Iis 7_Appdomain - Fatal编程技术网

Asp.net 分析器错误:无法加载类型";x";来自IIS7中虚拟目录中的appdomain

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应用程序的应用程序域中。然后,当我

所以我的场景有点滑稽,但这是有原因的

我有一个名为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并反映其成员和调用函数


一个有效的方法是在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);
    }