Backcolor = "# ccccff" bordercolor = "black" showfooter = "false"
Cellpadding = "3" cellspacing = "0" font-name = "verdana" font-size = "8pt"
Headerstyle-backcolor = "# aaaAadd" enableViewState = "false" /> form>
body>
html>
Most of this code is similar to the code used in the first implementation. The main difference is in the first line:
<% @ Page language = "c #" codebehind = "soliion.aspx.cs"
Autoeventwireup = "false" inherits = "solution"%>
The row tells the ASP.NET environment: The code hidden class implements the method referenced in this page. Because this page does not have any access to the database, even if the database access code changes, it is not necessary to modify the page. Those familiar with the user interface design can modify this code without any errors in the database access code. The second part of Model-Controller This is the following code hidden webpage:
Using system;
Using system.data;
Using system.data.sqlclient;
Public Class Solution: System.Web.ui.page
{
Protected system.Web.ui.WebControls.button submit;
Protected system.Web.ui.WebControls.DataGrid mydatagrid;
Protected system.Web.ui.webcontrols.dropdownlist recordingselect;
Private Void Page_Load (Object Sender, System.EventArgs E)
{
IF (! ispostback)
{
String selectcmd = "select * from recording";
SqlConnection myconnection =
NEW SQLCONNECTION
"Server = (local); database = recordings; trusted_connection = yes");
Sqldataadapter mycommand = new sqldataadapter (selectcmd, myconnection);
DataSet DS = New DataSet ();
MyCommand.Fill (DS, "Recording");
Recordingselect.datasource = ds;
Recordingselect.DataTextField = "Title";
Recordingselect.datavaluefield = "id";
Recordingselect.database ();
}
}
Void Submitbtn_Click (Object Sender, Eventargs E)
{
String selectcmd =
String.Format
"SELECT * from track where recordingId = {0} Order by id",
(String) RecordingSelect.SelectedItem.Value;
SqlConnection myconnection =
NEW SQLCONNECTION
"Server = (local); database = Recordings; trusted_connection = yes"); sqldataadapter mycommand = new sqldataadapter (selectcmd, myconnection);
DataSet DS = New DataSet ();
MyCommand.fill (DS, "Track");
MyDataGrid.dataSource = DS;
MyDataGrid.databind ();
}
#Region Web Form Designer Generated Code
Override protected void oninit (Eventargs E)
{
//
// Codegen: This call is necessary for the ASP.NET Web Form Designer.
//
InitializationComponent ();
Base.onit (E);
}
///
/// Designer Support for the method necessary - Do not use the code editor to modify
/// This method is content.
///
Private vidinitiRizeComponent ()
{
This.Submit.Click = new system.eventhandler (this.submitbtn_click);
This.Load = New System.EventHandler (this.page_load);
}
#ndregion
}
This code has been moved from a single ASP.NET page to a separate file. Several grammar changes are required to link two entities. The name of the member variable defined in the class is the same as the name referenced in the Solution.aspx file. Another aspect of an explicit definition is that how the controller links an event that responds to the operation that must be performed. In this example, the InitializationComponent method links two events. The first is the LOAD event, which is linked to the Page_Load function. The second is the Click event, which triggers the operation of the SubmitBTN_Click function after clicking the "Submit" button. The code hidden function is a good mechanism that separates the view role with the model role and the controller role. This feature may become less suitable when you need to let other pages reuse the code in the code hidden class. From a technical point of view, the code in the reuse code hidden web page is possible, but it is not recommended to do this because this will increase the interaction of all the web pages of the shared code hidden class. Model-View-Controller Refactoring To resolve the last problem, you need to further separate the model code to the controller. The view code is the same as the code in the previous implementation. The code example below describes the model and is only related to the database; it does not contain any code-related code (depending on the ASP.NET code):
Using system;
Using system.collections;
Using system.data;
Using system.data.sqlclient;
Public Class DatabaseGateway
{
Public Static DataSet GetRecordings ()
{
String selectcmd = "select * from recording";
SqlConnection myconnection =
NEW SQLCONNECTION
"Server = (local); database = recordings; trusted_connection = yes");
SqlDataAdapter mycommand = new sqldataadapter (selectcmd, myconnection); DataSet DS = New Dataset ();
MyCommand.Fill (DS, "Recording");
Return DS;
}
Public Static DataSet GetTracks (String RecordingID)
{
String selectcmd =
String.Format
"SELECT * from track where recordingId = {0} Order by id",
RecordingID);
SqlConnection myconnection =
NEW SQLCONNECTION
"Server = (local); database = recordings; trusted_connection = yes");
Sqldataadapter mycommand = new sqldataadapter (selectcmd, myconnection);
DataSet DS = New DataSet ();
MyCommand.fill (DS, "Track");
Return DS;
}
This is the only file that relies on the database. This class is a good example of the Table Data Gateway mode. Table Data Gateway contains all SQL code for accessing a single table or view: select, insert, update, and delete. Other code calls its method to interact with the database. [Fowler03] Controller This reconstruction uses code hidden features to rewrite the model code to adapt to the data controls present on the page, and map the event forwarded the controller to the specific method of operation. Because the model here returns a DataSet object, its work is very simple. The code is the same as the view code, does not rely on the way data from the database.
Using system;
Using system.data;
Using system.collections;
Using system.Web.ui.webcontrols;
Public Class Solution: System.Web.ui.page
{
Protected system.Web.ui.WebControls.button submit;
Protected system.Web.ui.WebControls.DataGrid mydatagrid;
Protected system.Web.ui.webcontrols.dropdownlist recordingselect;
Private Void Page_Load (Object Sender, System.EventArgs E)
{
IF (! ispostback)
{
DataSet DS = DatabaseGateway.getRecordings ();
Recordingselect.datasource = ds;
Recordingselect.DataTextField = "Title";
Recordingselect.datavaluefield = "id";
Recordingselect.database ();
}
}
Void Submitbtn_Click (Object Sender, Eventargs E)
{
DataSet DS =
Databasegateway.gettracks
(String) RecordingSelect.SelectedItem.Value;
MyDataGrid.dataSource = DS; mydatagrid.databind ();
}
#Region Web Form Designer Generated Code
Override protected void oninit (Eventargs E)
{
//
// Codegen: This call is necessary for the ASP.NET Web Form Designer.
//
InitializationComponent ();
Base.onit (E);
}
///
/// Designer Support for the method necessary - Do not use the code editor to modify
/// This method is content.
///
Private vidinitiRizeComponent ()
{
This.Submit.Click = new system.eventhandler (this.submitbtn_click);
This.Load = New System.EventHandler (this.page_load);
}
#ndregion
}
The test can make the model code test easier by separating the model with the ASP.NET environment. In order to test this code in the ASP.NET environment, the output must be tested. This means that HTML needs to be read and determine if it is correct, which is less lengthy and easy to generate errors. This lengthy process can be avoided by separating the model to run without ASP.NET, and can be avoided and test code separately. The following is an example unit test of the model code in NUnit (http://nunit.org):
Using system;
Using nunit.framework;
Using system.collections;
Using system.data;
Using system.data.sqlclient;
[TestFixTure]
Public Class GatewayFixTure
{
[TEST]
Public void tracks1234Query ()
{
DataSet DS = DatabaseGateway.getTracks ("1234");
Assertion.assertequals (10, DS.Tables ["track"]. Rows.count);
}
[TEST]
Public void TRACKS2345QUERY ()
{
DataSet DS = DatabaseGateway.getTracks ("2345");
Assertion.assertequals (3, DS.Tables ["track"]. Rows.count);
}
[TEST]
Public void recordings ()
{
DataSet DS = DatabaseGateway.getRecordings ();
Assertion.assertequals (4, DS.Tables ["Recording"]. Rows.count);
DataTable Recording = DS.TABLES ["Recording"];
Ask.ASSERTEQUALS (4, Recording.Rows.count);
DataRow Firstrow = Recording.Rows [0];
String Title = (String) FIRSTROW ["Title"];
Ask.ASSERTEQUALS ("UP", Title.trim ());
}
}