実行時の ASP.NET マスター ページの設定
-
08-06-2019 - |
質問
私は、実行時に変更可能な 2 つ以上の外観をサポートできる必要があるサイトに取り組んでいます。CSS スイッチで変更を処理できればよかったのですが、デザインごとに異なるマスターページを使用する必要があるようです。
では、実行時にマスターページを設定する最良の方法は何でしょうか?Page.MasterPageFile は、Page.OnPreInit イベントでのみ設定できます。解決策は、すべてのページを PreInit イベントを処理する共通ベースから継承させるか、それを行う HttpModule を使用することのようです。
何かアドバイス?
解決
以前にこれを一度行ったことがあり、まさにあなたが説明したことを行いました(すべてのページがOnPreInitイベントでカスタムページから継承されるようにしました)。また、別のマスター ページを必要としない画像/CSS 変更を行うために Page.StyleSheetTheme を設定するために、Global.asax.cs にカスタム Application_PreRequestHandlerExecute がありました。
他のヒント
2 つの異なるマスター ページではなく、異なるユーザー コントロールとコンテンツ HTML リテラルを動的に読み込む 1 つのマスターを用意するのはどうでしょうか?
あなたの痛みが分かります。これに関する問題を約 1 時間 (それ以上ではないにしても) 探しましたが、成功しませんでした。ページ数が数百ある場合に、「各ページの PreInit から呼び出すだけ」というのは、単なる無味乾燥な答えではありません。しかし、各ページをただ解決するよりも、解決策を探すのに多くの時間を費やしていることに気づきました。
ただし、Profile プロパティに基づいて MasterPageFile を設定したかったので、各ページに約 5 行のコードが必要となり、メンテナンス性の悪夢になりました。とにかく、「同じことを繰り返さない」ですよね?
そこで、これをより簡単かつ保守しやすくするために、App_Code フォルダー内のモジュールに Extension メソッドを作成しました。
Public Module WebFunctions
<System.Runtime.CompilerServices.Extension()> _
Public Sub SetMaster(ByVal page As Page)
Dim pb As ProfileCommon = DirectCast(HttpContext.Current.Profile, ProfileCommon)
If pb IsNot Nothing Then
page.MasterPageFile = pb.MasterPage
End If
End Sub
End Module
そして、各ページの PreInit で、これを呼び出すだけです。
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Me.SetMaster()
End Sub
PreInit を処理し、適切なマスター ページをロードするために必要な 1 行のコードを挿入するのは非常に簡単です。
this.Page.MasterPageFile = "~/default.master";
このルートを選択しないやむを得ない理由がない場合は、PreInit をどこで処理するかに関係なく、私ならそうするでしょう。
ページの見た目がどのように決まるのか知りたいです。ユーザーがボタンをクリックしてテーマを変更するのでしょうか?サイトにアクセスするために使用された URL に基づいていますか?
マスター ページではコード ビハインドがサポートされているため、1 つのマスター ページにロジックを組み込んで、何を表示するかを決定できます。
いくつかのサイトがユーザーのクリックに基づいて Cookie を設定し (フォント サイズやページ幅を変更するため)、それらの Cookie の値に基づいて異なる CSS ファイルを適用しているのを見てきました。Cookie が存在しない場合は、デフォルトのルック アンド フィールが表示されます。
編集:
ここでのもう 1 つの考えは、CSS を単に切り替えようとしている場合、スタイル タグをサーバーで実行するように設定し、実行時にそれにプロパティを割り当てることです。この場合も、単一のマスター ページを使用し、おそらく PreInit イベント ハンドラーにコードをマスター ページの分離コードに配置する必要があります。
私はこのソリューションを実装したことがないので、 <HEAD> タグ全体をサーバーで実行する必要があるかどうかはわかりません。
<html>
<head id="Head" runat="server">
<style id="StylePlaceholder" runat="server" type="text/css"></style>
</head>
次のような基本クラスからすべてのページを継承します。
public class PageBase : System.Web.UI.Page
{
public PageBase()
{
this.PreInit += new EventHandler(PageBase_PreInit);
}
void PageBase_PreInit(object sender, EventArgs e)
{
this.MasterPageFile = "~/MyMasterPage.Master";
}
}