Purpose:
Realize using the .cs file in MasterPage to replace PageBase in the project.
motivation:
The motivation for writing this article comes from a project reconstruction. In the B/S architecture project of .Net Framwork 2.0, both PageBase and MasterPage technologies were used. It was found that every time the page is accessed, the page accesses PageBase and MasterPage at the same time, which not only causes performance degradation, but may even cause problems in future project function expansion and adjustment. Hidden logic errors.
Technical aspects:
PageBase: A technology often used in .Net Framework 1.1 to encapsulate the same functionality of multiple pages. The PageBase.cs class inherits from the System.Web.UI.Page class. The Web pages in the project inherit from the PageBase.cs class. By overriding the page initialization method in the base class, the business functions in PageBase are called, such as: url parameters. Verification, saving visits and other functions (for specific implementation methods, please refer to Microsoft's official example duwamishi).
MasterPage: A new feature in .Net Framework 2.0. It physically includes two files: .Master file (html markup) and .cs file (C# code). The .Master file implements display layer drawing, and the .cs file implements specific functions. Web pages that inherit from MasterPage can inherit the display layer content in MasterPage. To draw a common header and footer and customize a unified layout, MasterPage is a good choice.
Simulation requirements:
Use MasterPage technology to replace PageBase to implement address bar parameter verification.
Let’s give a simple explanation. The Login table information in the database is as follows:
After logging in to the system, there are parameters in the url address bar, as follows:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
At this time, the user manually modifies the parameters in the URL address bar as:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
It is considered an illegal operation and the system will automatically jump back to the login page.
First code iteration:
1. Refer to the traditional PageBase method:
The traditional Page approach is:
public class PageBase : System.Web.UI.Page
{
publicPageBase()
{
}
/**////
/// Entry method
///
protected void Initialize()
{
//Insert common business logic
}
}
Web page:
public partial class TestPage : PageBase
{
//Traditional method of calling PageBase
/**/////
/// Override the base class OnPreInit() method and call the general verification method
///
///
protected override void OnInit(eventargs e)
{
base.Initialize();
}
}
Follow this approach and move the code in PageBase into MasterPage:
MasterPage.cs:
public partial class MyMasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Call verification method
Initialize();
}
}
}
Modify the code in the web page to:
public partial class TestPage : System.Web.UI.Page
{
// Imitate the PageBase method and call the method in Master
/**////
/// Override the base class OnPreInit() method and call the general verification method
///
///
protected override void OnInit(eventargs e)
{
// Get the master page reference
MyMasterPage myMasterPage = (MyMasterPage)this.Master;
//Call the general verification method in the master page
if (!IsPostBack)
{
myMasterPage.Initialize();
}
}
}Replace the Initialize() method in MasterPage with the one in the instance, test code:
Step 1: Log in to the system with the username zhangsan, and the login is successful.
The page shows that zhangsan is welcome to log in.
The url address shows:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
Step 2: Manually modify the url address bar: as follows:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
The page will not display the welcome lisi login, but will jump back to the login page.
Reflection: Although the function is implemented, there are still some unsatisfactory links:
1. The method called by the subclass in Master must be a public method;
2. Although there is no need to modify the inheritance of the Web page, you still have to mechanically copy and paste and override the OnInit() method of the base class.
In order to eliminate these lingering feelings, I started:
Second code iteration:
Modify the code in MasterPage.cs:
public partial class MyMasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Call verification method
CheckLogin();
}
}
/**////
/// Verify whether the access is legal
///
private void CheckLogin()
{
// If the number in the url or the number in the cookie
if (string.IsNullOrEmpty(Request.QueryString["id"])
|| string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}//If the number in the url does not match the number in the cookie, return to the login page
else if (int.Parse(Request.QueryString["id"]) != int.Parse(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}
}
}After reconstruction, the Web page can not be modified in any way. MasterPage automatically calls the verification method in its own Page_Load() method, and sets the verification method to private, which can only be called by MasterPage itself to improve security. At this point, the code seems to be ideal. Test:
Step 1: Log in to the system with the username zhangsan.
The user login page is still displayed.
Test failed.
Use breakpoints to trace the code and find that the problem occurs in the code snippet in the CheckLogin() method in MasterPage.cs:
if (string.IsNullOrEmpty(Request.QueryString["id"])
|| string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}
Since the login page inherits from MasterPage, the verification method in MasterPage.cs is automatically called when the page is loaded, and its own parameters do not satisfy the string.IsNullOrEmpty() method, so it jumps back to the login page. The login page is loaded again. The verification method in the base class is called, thus forming an infinite loop.
In PageBase technology, Web pages can selectively inherit from PageBase, but in MasterPage technology, in order to obtain a consistent display layer effect, the selectivity of Web pages to inherit MasterPage is very low, and we should not create the same display by creating a new one. , MasterPage without verification code is used to inherit Web pages that do not need to inherit the base class functions. This method is obviously unreasonable. In order to solve this problem, the third iteration was started:
Import the configuration file:
As you can see, the pages that need to be verified are identified (needvalidate="true").
Create Xml data access class:
public class XmlDAL
{
private static string filePath = string.Empty;
static XmlDAL()
{
//Initialize configuration file path
filePath = HttpContext.Current.Request.MapPath("~/App_Data/xml/" + "Pages.xml");
}
/**////
/// Get the list of pages that need to be verified
///
///
public static IList
{
IList
// If the specified configuration file exists
if (System.IO.File.Exists(filePath))
{
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filePath);
// Get the root node of the configuration file
XmlNode root = xmlDoc.DocumentElement;
string xpath = "/pages/testpage/page[@needvalidate='true']";
XmlNodeList nodeList = root.SelectNodes(xpath);
// Convenience node collection
foreach (XmlNode node in nodeList)
{
pages.Add(node.Attributes["title"].Value);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
return pages;
}
}
Refactor the code in MasterPage.cs and add the IsValidateNeeded(string url) method to detect whether the current page requires verification. Modify the verification method:
public partial class MyMasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Call verification method
CheckLogin();
}
}
/**////
/// Verify whether the access is legal
///
private void CheckLogin()
{
// Determine whether the currently accessed page requires verification
if (IsValidateNeeded(Request.RawUrl))
{
// If the number in the url or the number in the cookie
if (string.IsNullOrEmpty(Request.QueryString["id"])
|| string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}//If the number in the url does not match the number in the cookie, return to the login page
else if (int.Parse(Request.QueryString["id"]) != int.Parse(CookieUtil.ReadCookieByKey("id")))
{
Response.Redirect("Login.aspx");
}
}
}
/**////
/// Verify whether the current page requires verification
///
/// Current page name
///
private bool IsValidateNeeded(string url)
{
bool isNeeded = false;
// GetValidatePages() method returns the list of pages that need to be verified
IList
IEnumerator
while (ie.MoveNext())
{
// If the current page requires verification
if (url.Contains(ie.Current))
//Return to the status requiring verification
return isNeeded = true;
}
return isNeeded;
}
}
To test:
Step 1: Log in to the system with the username zhangsan, and the login is successful.
The page shows that zhangsan is welcome to log in.
The url address shows:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
Step 2: Manually modify the url address bar: as follows:
http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
The page will not display the welcome lisi login, but will jump back to the login page.
This concludes my code iteration.
Code download: