在引用预编译母版页时无法加载“ASP.xxx”类型

时间:2011-04-27 16:12:14

标签: asp.net master-pages pre-compilation

我正在尝试预编译几个母版页(不可更新)以在多个应用程序之间共享它们。我正在编译的项目是一个网站。引用预编译程序集的项目是Web应用程序。但是,每当我尝试从客户端引用母版页时,我都会收到“无法加载”类型的“ASP.xxx_master”。

<%@ Master Language="C#" Inherits="ASP.sitebase_master" %>

我的预编译母版页看起来像这样。

<%@ Master Language="C#" ClientIDMode="Static" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org  /TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="AspNetHead" runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />   
    <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=7" /><![endif]-->
    <asp:ContentPlaceHolder ID="MetaContent" runat="server" />
    <title>Web Portal</title>   
    <link href="/media/css/style.css" rel="stylesheet" type="text/css" />
    <link href="/media/js/plugins/colorbox/colorbox.css" rel="stylesheet" type="text/css" />
    <asp:ContentPlaceHolder ID="StyleContent" runat="server" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js" type="text/javascript" language="javascript"></script>
    <script src="/media/js/plugins/colorbox/jquery.colorbox-min.js" type="text/javascript" language="javascript"></script>
    <script src="/media/js/plugins/filestyle/jquery.filestyle.min.js" type="text/javascript" language="javascript"></script>
    <script src="/media/js/portal.master.js" type="text/javascript" language="javascript"></script>
    <script language="javascript" type="text/javascript">
        PORTAL.debug.init();
        PORTAL.init();
    </script>
    <asp:ContentPlaceHolder ID="ScriptContent" runat="server" />
</head>
<body>
    <div id="hld">  
        <div class="wrapper">
            <form id="AspNetForm" runat="server">
                <asp:ContentPlaceHolder ID="BodyContent" runat="server" />  
            </form>
            <asp:ContentPlaceHolder ID="FooterContent" runat="server" />
        </div>
    </div>
</body>

我很难过。不知道为什么类型没有解决。有人有建议吗?这两个项目(预编译的网站和客户端Web应用程序)都是为ASP.NET 4.0构建的。

编辑:以下是预编译程序集的依赖项列表。没有第三方参考。

mscorlib程序, 系统, 的System.Web

UDPATE 1

嗯,这个问题的快速解决方法是指定母版页的完整路径。

<%@ Master Language="C#" Inherits="ASP.sitebase_master, App_Web_sitebase.master.cdcab7d2" %>

这样做之后,我收到以下错误:

  

尝试加载字符串资源时发生错误(FindResource失败,错误为-2147023083)。

在做了一些研究之后,这似乎与在母版页中解析HTML标记的方式有关。还不完全确定。我没有深入挖掘它。总的来说,我无法相信这是分享控制的推荐方式,因为它绝对是令人难以置信的愚蠢。

更新2

我无法从中获得任何有价值的东西。它看起来很讨厌头部的“脚本”标签,但我不知道为什么。主页面适用于单个脚本包括。一旦我开始添加更多,我就会一直收到这个错误。在浪费了整整一天之后,我最终向Microsoft提交了bug report。如果有人想碰它,请做。

更新3

在MS没有回复之后我花了几天时间调试这个。这是我的发现。我最初认为CodeDOM提供程序生成的代码正在寻找一种.NET资源,该资源在发布时不会以某种方式嵌入到程序集中。我错了。经过一些调查后,看起来正在发生的事情是在母版页达到一定大小之后,其中一大块存储在程序集的PE数据目录部分的资源表中。事实上,在PE资源查看器中查看生成的程序集之后,我能够通过在资源表中找到我的所有脚本包含来确认这一点。现在,这是实际问题。发生的事情是CodeDOM提供程序生成对Win32 FindResource的调用,以从资源表中提取该资源。但是,FindResource不能在内存中的程序集上工作,只能在磁盘上工作。所以它失败了上述例外。我已经接近了,但仍然没有解决方法。

1 个答案:

答案 0 :(得分:2)

我终于有了解决方法。它不漂亮,但它解决了这个问题。显然使用LoadControl预加载预编译的MasterPages会加载FindResource无法找到的所有资源。所以,这就是我所做的一切。

在我的客户端应用程序中,我创建了一个虚拟母版页(即Dummy.Master),它引用了我的预编译母版页,如下所示:

<%@ Master Language="C#" Inherits="ASP.sitebase_master, App_Web_sitebase.master.cdcab7d2" %>

现在,任何引用Dummy.Master的.aspx页面都需要预加载预编译的MasterPage类型,如下所示:

        protected override void OnPreInit(EventArgs e)
        {
            ASP.sitebase_master mp = (ASP.sitebase_master)Page.LoadControl(typeof(ASP.sitebase_master), null);

            base.OnPreInit(e);
        }

我不知道为什么会这样,但确实如此。此代码必须在MasterPage解析之前运行,因此PreInit运行良好。在Reflector中浏览.NET代码几秒钟之后,看起来LoadControl在尝试加载某个控件类型时实际上会对某些程序集进行编译。所以也许在那里加载PE资源数据部分。把它放在最好的位置是我认为所有页面都可以继承的基类。此外,每个加载的控件(在这种情况下是母版页)都应该被缓存。 Here is a good article explaining just that.

希望这对帮助我的人有所帮助。对我来说这是一个相当大的表演限制。