Separation of program architecture and program code in ASP. NET

Source: Internet
Author: User
A year ago, when I got a PHP named twig Program It is hard to imagine that all the functions (calendar, email, and personalization) of twig are in the same PHP file (index. php3) Execution completed, thanks to the author's adoption of the program Code The idea of separation from the page architecture, but I also saw that despite the great efforts made by the author, due to the limitations of PHP, the program did not really achieve the separation of code and architecture, index. the main file php3 has too many functions to execute, so there are quite a lot of module files in its require, so the entire file is still very messy, I am ignorant, it took half a month, only then can I really understand the framework of the program and analyze the code. No one knows it ......).

The twig program has a great impact on my subsequent programming, but even such a piece of work still does not get rid of the mixed situation of program code and HTML code.

Separating program code from page architecture is a dream of web programmers for many years. In ASP. before the emergence of net, both ASP, PHP and JSP, program code and HTML code were mixed together. This approach, although praised in the early stages of web technology, but over time, its disadvantage is becoming more and more obvious. When the program code is very long, the HTML code is mixed with it, and the readability of the program becomes very poor, which makes it impossible to distinguish the page architecture that the program really wants to represent.

ASP. NET implements code separation through codebehind, user control, and custom control. This is an amazing improvement. You can see in this article how clear the structure of ASP. NET program after code separation is.

For ease of understanding, the design page here is relatively simple, the page is divided into three main parts, the header contains an adrotator control (used to display ads) and a label control (used to display the current ad link address); the middle is a login page, including two textbox controls (used to enter the user name and password respectively), a label control (display whether the login is successful) and a button control (as the submit button); the bottom contains two label controls (display the current user name and user permissions respectively ).

Familiar with ASP. net friends, will immediately realize that the header because of the use of the adrotator control, so there must be an onadcreated event to display the corresponding link in the label control; and in the middle of the due to the use of the button control as the submit button, therefore, an onclick event must be processed.

1 codebehind

First, let's take a look at how to use the codebehind method to separate code from the page architecture. The following source code is the main ASP. NET program -- example1.aspx:

<% @ Page src = "CS \ eventhandle. cs" inherits = "aspcn" %>
<HTML>
<Head>
<Title> </title>
</Head>
<Body>
<Form runat = "server">
<Asp: Panel id = "Header" runat = "server">
<Asp: adrotator id = "ad" advertisementfile = "adbanners \ Ad. xml" borderwidth = "0" onadcreated = "adcreated" runat = "server"/> <br>
Current ad link: <asp: Label id = "lbladtext" forecolor = "red" runat = "server"/>
</ASP: Panel>

<Asp: Panel id = "Logon" runat = "server">
<Table>
<Tr> <TD colspan = "2" align = "center"> <B> logon window </B> </TD> </tr>
<Tr> <TD colspan = "2" align = "center"> <asp: label id = "lblmsgshow" forecolor = "red" runat = "server"/> </TD> </tr>
<Tr> <TD> User name: </TD> <asp: textbox id = "tbusername" runat = "server"/> </TD> </tr>
<Tr> <TD> password: </TD> <asp: textbox id = "tbpasswd" textmode = "password" runat = "server"/> </TD> </tr>
<Tr> <TD> <asp: button id = "btnsubmit" text = "login" onclick = "submit_click" runat = "server"/> </TD> </tr>
</Table>
</ASP: Panel>

<Asp: Panel id = "footer" runat = "server">
Username: <asp: Label id = "lblusername" font-name = "Arial" forecolor = "red" text = "" runat = "server"/>

Permission: <asp: Label id = "lblpurview" font-name = "Arial" text = "" forecolor = "red" runat = "server"/>
</ASP: Panel>
</Form>
</Body>
</Html>

In the routine, you can clearly see that the program does not contain any C #, VB, JavaScript to handle onadcreated and onclick events, but runs this program, the program can be used normally (2-1 and 2-2 ). This is the result of codebehinde. event processing has been transferred to other programs for definition execution. Please note the information in the first line in this example:

<% @ Page src = "CS \ eventhandle. cs" inherits = "aspcn" %>

Usually in ASP. in the. NET program, the page command sets the language (using the language attribute) that the program should use. In this example, the language attribute is not displayed, but two new page attributes are displayed: SRC and inherits. The src attribute sets the real code location for event processing, and the inherits attribute sets the class name to be introduced. We can see that the file defining event processing in this example is eventhandle. cs. Let's take a look at its specific content: using system;
Using system. Data;
Using system. Data. sqlclient;
Using system. Web;
Using system. Web. UI;
Using system. Web. UI. webcontrols;
Using system. Web. UI. htmlcontrols;
Public class aspcn: Page
{
// Declare controls in web form
Public label lbladtext, lblusername, lblpurview, lblmsgshow;
Public textbox tbusername, tbpasswd;
Public button btnsubmit;
Public adrotator ad;

Private string strconnstring = "Server = (local) \ feidao; database = aspcn; trusted_connection = yes ";

// Process the adrotator control creation event
Public void adcreated (Object SRC, adcreatedeventargs E)
{
Lbladtext. Text = E. alternatetext;
}

Public void submit_click (Object sender, eventargs E)
{
Sqlconnection myconn = new sqlconnection (strconnstring );
Myconn. open ();
String strusername, strpassword, strselect;
Strusername = tbusername. text;
Strpassword = tbpasswd. text;
Strselect = "select * From bbs_user where id = '" + strusername + "' and Password = '" + strpassword + "'";
Sqlcommand mycomm = new sqlcommand (strselect, myconn );
Sqldatareader DR = mycomm. executereader ();
If (dr. Read ())
{
// Login successful
Lblmsgshow. Text = "Login successful ";
Lblusername. Text = Dr ["ID"]. tostring ();
Lblpurview. Text = Dr ["purview"]. tostring ();
}
Else
{
// Login Failed
Lblmsgshow. Text = "Login Failed ";
}
Dr. Close ();
Myconn. Close ();
}
}

Event processing is defined in a class (in this example, aspcn is case sensitive). This class must inherit the page class because it needs to be associated with web forms.

Analysis program, you can see that the event processing operations in the program are the same as ordinary programs without code separation, there is nothing special. (I have provided related comments in the program. I believe it will help you understand the program)

After codebehind technology is used, you need to write more code, such as declare controls. Maybe you do not like to write more code, but you must also see that after codebehind technology is used, the readability of the main program is greatly increased. In example1.aspx, I believe that you will soon be able to differentiate the various parts of the page architecture. Do you think these architectures can be seen so clearly in other technologies?
(The program here is only used for demonstration. Haha, don't catch me any quotation marks, vulnerabilities, etc)

2. User Control)
Codebehind technology truly achieves the separation of code and architecture, a significant step forward than the previous technology, but its defects are also obvious, such as the login area in the middle of the home page, if there is a lot of content, the code displayed in HTML still occupies a large area, and the readability of the program is reduced.

ASP. NET also provides a solution, which is the user control.

User Control we can regard it as a server control without compilation. If it is a control, it will certainly follow the control's usage method. Each panel in example1.aspx is regarded as a control. Therefore, the main part of example1.aspx can be reduced to only three rows by using the user control:

<% @ Register tagprefix = "aspcn" tagname = "Header" src = "usercontrols/header. ascx" %>
<% @ Register tagprefix = "aspcn" tagname = "Logon" src = "usercontrols/logon. ascx" %>
<% @ Register tagprefix = "aspcn" tagname = "footer" src = "usercontrols/footer. ascx" %>
<HTML>
<Head>
<Title> </title>
</Head>
<Body>
<Form runat = "server">
<Aspcn: Header id = "myheader" runat = "server"/>
<Aspcn: logon id = "mylogon" runat = "server"/>
<Aspcn: footer id = "myfooter" runat = "server"/>
</Form>
</Body>
</Html>

The execution result of this program is the same as that of codebehind, but the current ASP. Net program is easier to differentiate the page architecture.

<Aspcn: Header id = "myheader" runat = "server"/>
<Aspcn: logon id = "mylogon" runat = "server"/>
<Aspcn: footer id = "myfooter" runat = "server"/>

These three lines of code use three user controls. With so little code, you can clearly see that the page is divided into three parts.

To use a user control, you must use the register command. The tagprefix attribute defines a namespace name to ensure its uniqueness on this page. The tagname attribute defines a class) because the user control is compiled by CLR into a class for execution, each user control in this program must be given a unique name for distinction; the src attribute specifies the file name of the user control used (the user control uses. the end of ascx ).

The use of user controls is the same as that of common server controls:
<Namespace: class... runat = "server"/>
Namespace indicates the defined namespace, and class indicates the corresponding class name. Examples include:
<Aspcn: logon id = "mylogon" runat = "server"/>

The following is the specific content of the user control used in the user control display program:

Header. ascx (header user control)

<Script language = "C #" runat = "server">
Private void adcreated (Object SRC, adcreatedeventargs E)
{
Lbladtext. Text = E. alternatetext;
}
</SCRIPT>
<Asp: adrotator id = "ad" advertisementfile = ".. \ adbanners \ Ad. XML "borderwidth =" 0 "onadcreated =" adcreated "runat =" server "/> <br>
Current ad link: <asp: Label id = "lbladtext" forecolor = "red" runat = "server"/>

Logon. ascx (logon user control)

<% @ Import namespace = "system. Data" %>
<% @ Import namespace = "system. Data. sqlclient" %>
<Script language = "C #" runat = "server">
Protected string strconnstring = "Server = (local) \ feidao; database = aspcn; trusted_connection = yes ";
// Define the attributes of usercontrol
Public String Username
{
Get
{
Return tbusername. text;
}
Set
{
Tbusername. Text = value;
}
}
Public String Password
{
Get
{
Return tbpasswd. text;
}
Set
{
Tbpasswd. Text = value;
}

}

// Event processing
Private void submit_click (Object sender, eventargs E)
{
Sqlconnection myconn = new sqlconnection (strconnstring );
Myconn. open ();
String strusername, strpassword, strselect;
Strusername = tbusername. text;
Strpassword = tbpasswd. text;
Strselect = "select * From bbs_user where id = '" + strusername + "' and Password = '" + strpassword + "'";
Sqlcommand mycomm = new sqlcommand (strselect, myconn );
Sqldatareader DR = mycomm. executereader ();
If (dr. Read ())
{
// Login successful
Lblmsgshow. Text = "Login successful ";
Session ["username"] = Dr ["ID"]. tostring ();
Session ["purview"] = Dr ["purview"]. tostring ();
}
Else
{
// Login Failed
Lblmsgshow. Text = "Login Failed ";
}
Dr. Close ();
Myconn. Close ();
}
</SCRIPT>
<Table>
<Tr> <TD colspan = "2" align = "center"> <B> logon window </B> </TD> </tr>
<Tr> <TD colspan = "2" align = "center"> <asp: label id = "lblmsgshow" forecolor = "red" runat = "server"/> </TD> </tr>
<Tr> <TD> User name: </TD> <asp: textbox id = "tbusername" runat = "server"/> </TD> </tr>
<Tr> <TD> password: </TD> <asp: textbox id = "tbpasswd" textmode = "password" runat = "server"/> </TD> </tr>
<Tr> <TD> <asp: button id = "btnsubmit" text = "login" onclick = "submit_click" runat = "server"/> </TD> </tr>
</Table>

Footer. ascx (footer user control)

<Script language = "C #" runat = "server">
Private void page_load (Object SRC, eventargs E)
{
If (session ["username"]! = NULL)
{
Lblusername. Text = (string) session ["username"];
Lblpurview. Text = (string) session ["purview"];
}
}
</SCRIPT>
Username: <asp: Label id = "lblusername" font-name = "Arial" forecolor = "red" text = "" runat = "server"/>

Permission: <asp: Label id = "lblpurview" font-name = "Arial" text = "" forecolor = "red" runat = "server"/>

Each control contains its own display code and corresponding program code.

We can make some common functions into fixed user controls. When necessary, we can directly use them without using annoying crtl + C, CTRL + V to "copy" and "Paste" a long pile of code.

The user control not only separates the program code from the page framework, but also increases the code reusability.

3. Custom Control)

User Controls are a good choice, but since each user control is an ascx file, when there are many controls, their use is relatively messy. In this case, we want to integrate some similar controls. In the program, we only need to reference them once. This is a good idea. We have made this idea more professional: "importing multiple classes into the same namespace )". Well, how are you familiar with this sentence? Check the definition of the server control. Do you find this sentence is...

The following describes how to write server controls. Writing server controls is not easy. NET platform has a deep understanding, suitable for advanced users, so here I will not specifically describe the Server Control writing steps (to elaborate on this, you have to write a book ). Please compare Custom ControlsSource codeFor more information about the differences with user controls:

Using system;
Using system. Data;
Using system. Data. sqlclient;
Using system. drawing;
Using system. Web;
Using system. Web. UI;
Using system. Web. UI. webcontrols;
Namespace aspcn
{
// Header first
Public Class header: control, inamingcontainer
{
Private adrotator ad;
Private Label lbladtext;

Protected override void createchildcontrols ()
{
// Add adrotator AD control
AD = new adrotator ();
Ad. advertisementfile = "adbanners/Ad. xml ";
Ad. borderwidth = 0;
Ad. adcreated + = new adcreatedeventhandler (this. onadcreated );
This. Controls. Add (AD );

This. Controls. Add (New literalcontrol ("<br>" + "current ad link :"));
// Add the label Control
Lbladtext = new label ();
Lbladtext. forecolor = color. Red;
This. Controls. Add (lbladtext );
}
Private void onadcreated (Object sender, adcreatedeventargs E)
{
This. lbladtext. Text = E. alternatetext;
}
}
// Followed by Logon
Public class Logon: control, inamingcontainer
{
Private string strconnstring = "Server = (local) \ feidao; database = aspcn; trusted_connection = yes ";
Private Label lblmsgshow;
Private textbox tbusername, tbpasswd;
Public String Username
{
Get
{
Return tbusername. text;
}
Set
{
Tbusername. Text = value;
}
}

Protected override void createchildcontrols ()
{
// Add HTML tags
This. controls. add (New literalcontrol ("<Table> <tr> <TD colspan = \" 2 \ "align = \" center \ "> <B> logon window </B> </ TD> </tr> <TD colspan = \ "2 \" align = \ "center \"> "));
// Add the msgshow label Control
Lblmsgshow = new label ();
Lblmsgshow. forecolor = color. Red;
This. Controls. Add (lblmsgshow );
This. Controls. Add (New literalcontrol ("</TD> </tr> <TD> User name: </TD> <TD> "));
// Add the username and passwd textbox controls
Tbusername = new Textbox ();
This. Controls. Add (tbusername );
This. Controls. Add (New literalcontrol ("</TD> </tr> <TD> password: </TD> <TD> "));
Tbpasswd = new Textbox ();
Tbpasswd. textmode = textboxmode. Password;
This. Controls. Add (tbpasswd );
This. Controls. Add (New literalcontrol ("</TD> </tr> <TD> "));
// Add the btnsubmit button control
Button btnsubmit = new button ();
Btnsubmit. Text = "login ";
Btnsubmit. Click + = new eventhandler (this. submit_click );
This. Controls. Add (btnsubmit );
This. Controls. Add (New literalcontrol ("</TD> </tr> </table> "));
}
// Display complete
Private void submit_click (Object sender, eventargs E)
{
Sqlconnection myconn = new sqlconnection (strconnstring );
Myconn. open ();
String strusername, strpassword, strselect;
Strusername = tbusername. text;
Strpassword = tbpasswd. text;
Strselect = "select * From bbs_user where id = '" + strusername + "' and Password = '" + strpassword + "'";
Sqlcommand mycomm = new sqlcommand (strselect, myconn );
Sqldatareader DR = mycomm. executereader ();
If (dr. Read ())
{
// Login successful
This. lblmsgshow. Text = "Login successful ";
}
Else
{
// Login Failed
This. lblmsgshow. Text = "Login Failed ";
}
Dr. Close ();
Myconn. Close ();
}
}
// Finally, footer
Public class footer: control, inamingcontainer
{
Private string _ username, _ purview;

Public String Username
{
Get
{
Return _ username;
}
Set
{
_ Username = value;
}
}

Public String purview
{
Get
{
Return _ purview;
}
Set
{
_ Purview = value;
}
}

Public footer ()
{
_ Username = "Tourist ";
_ Purview = "NONE ";
}

Protected override void createchildcontrols ()
{
This. Controls. Add (New literalcontrol ("username :"));
Label lblusername = new label ();
Lblusername. forecolor = color. Red;
Lblusername. Font. Name = "Arial ";
Lblusername. Text = This. Username;
This. Controls. Add (lblusername );
// This. Controls. Add (New literalcontrol ("nbsp ;"));

This. Controls. Add (New literalcontrol ("permission :"));
Label lblpurview = new label ();
Lblpurview. forecolor = color. Red;
Lblpurview. Font. Name = "Arial ";
Lblpurview. Text = This. purview;
This. Controls. Add (lblpurview );
}
}
}

The above and the program import all the functions to be implemented into the custom control. In the program, we can see that the aspcn namespace contains three classes (header, logon, and footer). These three classes are the three main parts of the framework.

To use a custom control, you must also compile the original code.

CSC/T: Library/out: aspcn. dll/R: system. Data. dll, system. Web. dll, system. Drawing. dll customcontrols. CS

I will not repeat the usage of C # program compilation commands here. Note that the compiled file name must be the same as the namespace name in the control.

The compiled DLL cannot be used. We must put it in. the most famous directory on the net platform --/bin. The bin directory (which can be created if it does not exist) stores all the custom controls and components in the current virtual directory, CLR is executing ASP. net program will automatically search for files in this directory to find files with ASP.. Net Program matching namespace, class, and assembly.

After we put the compiled aspcn. dll program into the/bin directory, this self-compiled server control can be used.
(It should be declared that the communication between two classes is impossible because the variables such as session cannot be used when writing the server control, therefore, by default, the footer control does not change with the session content like the previous program. However, you can perform operations on the corresponding properties by performing common operations on the server control to achieve the same effect, save layout, not used)
Next let's take a look at the content of the main web form program:

<% @ Register tagprefix = "aspcn" namespace = "aspcn" assembly = "aspcn" %>
<HTML>
<Head>
<Title> </title>
</Head>
<Body>
<Form runat = "server">
<Aspcn: Header id = "myheader" runat = "server"/>
<Aspcn: logon id = "mylogon" runat = "server"/>
<Aspcn: footer id = "myfooter" runat = "server"/>
</Form>
</Body>
</Html>

It's quite simple and clear.
Referencing custom controls is also quite simple. You only need to set the tagprefix, namespace, and assembly attributes of the register command to aspcn.

Now, three methods for separating code from the page architecture in ASP. NET have been introduced.

The three methods have their own advantages and disadvantages. I prefer to use the user control and codebinde technology in combination, because they do not require compilation and are relatively easy to use. If you want to protect your code, custom Controls are of course your best choice.

I hope this article will be helpful for your programming.

PCN: Header id = "myheader" runat = "server"/>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.