0

複数のアプリケーション間で共有するために、いくつかのマスターページ(更新不可)をプリコンパイルしようとしています。私がプリコンパイルしているプロジェクトはWebサイトです。プリコンパイルされたアセンブリを参照するプロジェクトは、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サイトとクライアントWebアプリケーション)は、ASP.NET4.0用に構築されています。

編集:これは、プリコンパイルされたアセンブリの依存関係のリストです。サードパーティの参照はありません。

mscorlib、System、System.Web

UDPATE 1

この問題の簡単な解決策は、マスターページへのフルパスを指定することです。

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

それを行った後、次のエラーが発生します。

文字列リソースのロード中にエラーが発生しました(FindResourceがエラー-2147023083で失敗しました)。

いくつかの調査を行った後、これはHTMLマークアップがマスターページ内で解析される方法に関連しているようです。まだ完全にはわかりません。私はそれを深く掘り下げていません。全体として、これが絶対に、気が遠くなるほどばかげているので、これがコントロールを共有するための推奨される方法であるとは信じられません。

更新2

私はこれから価値のあるものを作ることができませんでした。ヘッドセクションの「script」タグが嫌いなようですが、理由はわかりません。マスターページは、単一のスクリプトインクルードでうまく機能します。さらに追加を開始するとすぐに、そのエラーが発生し続けます。これで丸一日を無駄にした後、私はマイクロソフトにバグレポートを提出することになりました。誰かがそれをぶつけたいなら、してください。

更新3

MSからの応答がなかった後、これをデバッグするためにさらに数日を費やしました。これが私の発見です。私は当初、CodeDOMプロバイダーによって生成されたコードが、公開時にアセンブリに埋め込まれなかった.NETリソースを探していると思っていました。私は間違っていた。調査の結果、マスターページが特定のサイズに達した後、そのチャンクがアセンブリのPEデータディレクトリセクションのリソーステーブルに保存されているようです。実際、PEリソースビューアで生成されたアセンブリを確認した後、リソーステーブルに含まれているすべてのスクリプトを見つけることでこれを確認できました。さて、これが実際の問題です。何が起こっているのかというと、CodeDOMプロバイダーはWin32 FindResourceへの呼び出しを生成して、リソーステーブルからそのリソースをプルします。ただし、FindResourceは ディスク上でのみ、メモリ内のアセンブリで動作します。したがって、上記の例外で失敗します。近づいていますが、まだ回避策はありません。

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タイプをプリロードする必要があります。

        保護されたオーバーライドvoidOnPreInit(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 に答える