目的:
MasterPage の .cs ファイルを使用して、プロジェクト内の PageBase を置き換えます。
モチベーション:
この記事を書く動機は、プロジェクトの再構築から来ています。 .Net Framwork 2.0 の B/S アーキテクチャ プロジェクトでは、PageBase と MasterPage の両方のテクノロジが使用されており、ページにアクセスするたびに、ページは PageBase と MasterPage に同時にアクセスするため、パフォーマンスが低下するだけでなく、ただし、将来のプロジェクト機能の拡張や調整で問題が発生する可能性もあります。
技術的な側面:
PageBase: 複数のページの同じ機能をカプセル化するために .Net Framework 1.1 でよく使用されるテクノロジ。 PageBase.cs クラスは System.Web.UI.Page クラスを継承します。プロジェクト内の Web ページは、基本クラスのページ初期化メソッドをオーバーライドすることによって、PageBase のビジネス関数が呼び出されます。例: URL パラメーター。検証、訪問の保存、その他の機能 (具体的な実装方法については、Microsoft の公式サンプル duwamishi を参照してください)。
MasterPage: .Net Framework 2.0 の新機能。物理的には、.Master ファイル (HTML マークアップ) と .cs ファイル (C# コード) の 2 つのファイルが含まれています。 .Master ファイルは表示レイヤーの描画を実装し、.cs ファイルは特定の機能を実装します。 MasterPage から継承した Web ページは、MasterPage の表示レイヤーのコンテンツを継承できます。共通のヘッダーとフッターを描画し、統一されたレイアウトをカスタマイズするには、MasterPage が適しています。
シミュレーション要件:
MasterPage テクノロジーを使用して PageBase を置き換え、アドレス バー パラメーターの検証を実装します。
簡単に説明すると、データベース内のログインテーブル情報は次のとおりです。
システムにログインすると、URL アドレス バーに次のようなパラメータが表示されます。
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
この時点で、ユーザーは URL アドレス バーのパラメータを次のように手動で変更します。
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
これは不正な操作とみなされ、システムは自動的にログイン ページに戻ります。
最初のコード反復:
1. 従来の PageBase メソッドを参照してください。
従来のページのアプローチは次のとおりです。
パブリック クラス PageBase : System.Web.UI.Page
{
publicPageBase()
{
}
/**//// <概要>
/// 入力方法
/// </概要>
protected void Initialize()
{
//共通のビジネスロジックを挿入
}
}
ウェブページ:
パブリック部分クラス TestPage : PageBase
{
//PageBase を呼び出す従来の方法
/**///// <概要>
/// 基本クラスの OnPreInit() メソッドをオーバーライドし、一般的な検証メソッドを呼び出します
/// </概要>
/// <param name="e"></param>
保護されたオーバーライド void OnInit(eventargs e)
{
Base.Initialize();
}
}
このアプローチに従って、PageBase のコードを MasterPage に移動します。
マスターページ.cs:
パブリック部分クラス MyMasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(オブジェクト送信者, EventArgs e)
{
if (!IsPostBack)
{
//呼び出し確認メソッド
初期化();
}
}
}
Web ページのコードを次のように変更します。
パブリック部分クラス TestPage : System.Web.UI.Page
{
// PageBase メソッドを模倣し、Master でメソッドを呼び出します
/**//// <概要>
/// 基本クラスの OnPreInit() メソッドをオーバーライドし、一般的な検証メソッドを呼び出します
/// </概要>
/// <param name="e"></param>
保護されたオーバーライド void OnInit(eventargs e)
{
// マスターページ参照を取得します
MyMasterPage myMasterPage = (MyMasterPage)this.Master;
//マスターページで一般的な検証メソッドを呼び出します
if (!IsPostBack)
{
myMasterPage.Initialize();
}
}
MasterPage の Initialize() メソッドをインスタンス内のメソッドに置き換えます。テスト コード:
ステップ 1: ユーザー名 zhangsan でシステムにログインすると、ログインは成功します。
このページには、zhangsan がログインを歓迎していることが示されています。
URL アドレスは次を示します。
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
ステップ 2: URL アドレス バーを次のように手動で変更します。
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
このページにはようこそ lisi ログインは表示されませんが、ログイン ページに戻ります。
反省: 機能は実装されましたが、まだ不十分なリンクがいくつかあります。
1. Master のサブクラスによって呼び出されるメソッドはパブリック メソッドである必要があります。
2. Web ページの継承を変更する必要はありませんが、基本クラスの OnInit() メソッドを機械的にコピー アンド ペーストしてオーバーライドする必要があります。
こうした未練を解消するために、私は次のことを始めました。
2 番目のコード反復:
MasterPage.cs のコードを変更します。
パブリック部分クラス MyMasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(オブジェクト送信者, EventArgs e)
{
if (!IsPostBack)
{
//呼び出し確認メソッド
CheckLogin();
}
}
/**//// <概要>
/// アクセスが合法かどうかを検証する
/// </概要>
プライベート void CheckLogin()
{
// URL 内の数値または Cookie 内の数値の場合
if (string.IsNullOrEmpty(Request.QueryString["id"])
|| string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}// URL の数値が Cookie の数値と一致しない場合は、ログイン ページに戻ります
else if (int.Parse(Request.QueryString["id"]) != int.Parse(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}
}
再構築後、Web ページはいかなる方法でも変更できなくなります。MasterPage は、独自の Page_Load() メソッドで検証メソッドを自動的に呼び出し、セキュリティを向上させるために MasterPage 自体によってのみ呼び出すことができる検証メソッドをプライベートに設定します。この時点で、コードは理想的であると思われます。
ステップ 1: ユーザー名 zhangsan でシステムにログインします。
ユーザーのログイン ページは引き続き表示されます。
テストは失敗しました。
ブレークポイントを使用してコードをトレースし、MasterPage.cs の CheckLogin() メソッドのコード スニペットで問題が発生していることを見つけます。
if (string.IsNullOrEmpty(Request.QueryString["id"])
|| string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}
ログイン ページは MasterPage から継承しているため、ページが読み込まれると MasterPage.cs の検証メソッドが自動的に呼び出され、その独自のパラメーターが string.IsNullOrEmpty() メソッドを満たさないため、ログイン ページに戻ります。ページが再度ロードされると、基本クラスの検証メソッドが呼び出され、無限ループが形成されます。
PageBase テクノロジでは、Web ページは PageBase から選択的に継承できますが、MasterPage テクノロジでは、一貫した表示レイヤ効果を得るために、MasterPage を継承する Web ページの選択性が非常に低く、同じ表示を作成する必要はありません。基底クラスの関数を継承する必要のない Web ページを継承するために、検証コードのない MasterPage が使用されるこの方法は明らかに不合理です。この問題を解決するために、3 回目の反復が開始されました。
設定ファイルをインポートします。
<?xml バージョン="1.0" エンコーディング="utf-8" ?>
<ページ>
<テストページ>
<page title="TestPage" url="TestPage.aspx" needvalidate="true"/>
<page title="ログイン" url="ログイン.aspx" needvalidate="false"/>
</テストページ>
<管理者ページ>
<page title="Page1" url="~/Admin/Page1.aspx" needvalidate="false"/>
<page title="Page2" url="~/Admin/Page2.aspx" needvalidate="false"/>
</管理ページ>
</ページ>
ご覧のとおり、検証が必要なページが特定されています (needvalidate="true")。
XML データ アクセス クラスを作成します。
パブリック クラス XmlDAL
{
プライベート静的文字列ファイルパス = string.Empty;
静的XmlDAL()
{
//設定ファイルのパスを初期化します
filePath = HttpContext.Current.Request.MapPath("~/App_Data/xml/" + "Pages.xml");
}
/**//// <概要>
/// 検証が必要なページのリストを取得します
/// </概要>
/// <returns>検証が必要なページのリスト</returns>
パブリック静的 IList<string> GetValidatePages()
{
IList<string> ページ = new List<string>();
// 指定した設定ファイルが存在する場合
if (System.IO.File.Exists(filePath))
{
試す
{
XmlDocument xmlDoc = 新しい XmlDocument();
xmlDoc.Load(ファイルパス);
// 設定ファイルのルートノードを取得します
XmlNode ルート = xmlDoc.DocumentElement;
文字列 xpath = "/pages/testpage/page[@needvalidate='true']";
XmlNodeList ノードリスト = root.SelectNodes(xpath);
// コンビニエンスノードのコレクション
foreach (nodeList 内の XmlNode ノード)
{
Pages.Add(node.Attributes["title"].Value);
}
}
catch (例外例)
{
新しい例外(例:メッセージ)をスローします。
}
}
ページを返す。
}
}
MasterPage.cs のコードをリファクタリングし、現在のページに検証が必要かどうかを検出する IsValidateNeeded(string url) メソッドを追加します。検証方法を変更します。
パブリック部分クラス MyMasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(オブジェクト送信者, EventArgs e)
{
if (!IsPostBack)
{
//呼び出し確認メソッド
CheckLogin();
}
}
/**//// <概要>
/// アクセスが合法かどうかを検証する
/// </概要>
プライベート void CheckLogin()
{
// 現在アクセスしているページに検証が必要かどうかを判断します
if (IsValidateNeeded(Request.RawUrl))
{
// URL 内の数値または Cookie 内の数値の場合
if (string.IsNullOrEmpty(Request.QueryString["id"])
|| string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}// URL の数値が Cookie の数値と一致しない場合は、ログイン ページに戻ります
else if (int.Parse(Request.QueryString["id"]) != int.Parse(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}
}
}
/**//// <概要>
/// 現在のページに検証が必要かどうかを検証します
/// </概要>
/// <param name="currentPage">現在のページ名</param>
/// <returns>ステータスを確認する必要があるかどうか</returns>
private bool IsValidateNeeded(文字列 URL)
{
ブール値が必要 = false;
// GetValidatePages() メソッドは検証が必要なページのリストを返します
IList<string> ページ = XmlDAL.GetValidatePages();
IEnumerator<文字列> ie = ページ.GetEnumerator();
while (ie.MoveNext())
{
// 現在のページに検証が必要な場合
if (url.Contains(ie.Current))
//検証が必要な状態に戻る
戻り値は必要 = true;
}
戻りが必要です。
}
}
テストするには:
ステップ 1: ユーザー名 zhangsan でシステムにログインすると、ログインは成功します。
このページには、zhangsan がログインを歓迎していることが示されています。
URL アドレスは次を示します。
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
ステップ 2: URL アドレス バーを次のように手動で変更します。
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
このページにはようこそ lisi ログインは表示されませんが、ログイン ページに戻ります。
これでコードの反復は終了です。
コードのダウンロード: