0

我正在尝试预编译一些母版页(不可更新)以在多个应用程序之间共享它们。我正在预编译的项目是一个网站。引用预编译程序集的项目是 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

我无法从中获得任何有价值的东西。它似乎讨厌头部中的“脚本”标签,但我不知道为什么。母版页适用于单个脚本包含。一旦我开始添加更多内容,我就会不断收到该错误。在为此浪费了一整天之后,我最终向微软提交了一份错误报告。如果有人想撞它,请做。

更新 3

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

4

1 回答 1

2

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

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

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

现在,任何引用 Dummy.Master 的 .aspx 页面都需要像这样预加载预编译的 MasterPage 类型:

        受保护的覆盖无效 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 资源数据部分。放置它的最佳位置是我想所有页面都可以继承的基类。此外,每个加载的控件(在本例中为母版页)都应该被缓存。这是一篇很好的文章来解释这一点。

希望这对某人有帮助,就像对我有帮助一样。这对我来说是一个相当大的表演障碍。

于 2011-05-03T05:00:00.923 回答