我正在尝试预编译几个母版页(不可更新)以在多个应用程序之间共享它们。我正在编译的项目是一个网站。引用预编译程序集的项目是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不能在内存中的程序集上工作,只能在磁盘上工作。所以它失败了上述例外。我已经接近了,但仍然没有解决方法。
答案 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.
希望这对帮助我的人有所帮助。对我来说这是一个相当大的表演限制。