Implement Model-View-Controller mode in ASP.NET

xiaoxiao2021-03-06  27

background:

When creating a web application with ASP.NET, based on the complexity of the program, the program must be split into different parts to reduce the recruitment of the code and reduce changes caused by future changes.

Implementation strategy:

To explain how to implement (MVC) models in ASP.NET - view-controller mode, and instructions to separate software into models, views, and controller roles, this is described as an example as an example. This sample program is a single page program with a drop-down box, which is the data in the database. As shown below.

When the user selects a record in the drop-down box and click the Submit button, the program searches from the database record from the database, and is displayed in the form of a list. Hereinafter, it will be implemented in three different implementations.

Single page mode

There are many ways to solve this problem in ASP.NET, and the simplest is also the most direct way is to put all the code in a file and name Solution.ASPX, and the code is as follows:

<% @ Import namespace = "system.data"%>

<% @ Import namespace = "system.data.sqlclient"%>

start </ title></p> <p><script language = "c #" runat = "server"></p> <p>Void Page_Load (Object Sender, System.EventArgs E)</p> <p>{</p> <p>String selectcmd = "select * from recording";</p> <p>SqlConnection MyConnection = New SqlConnection ("Server = (local); Database = Recordings; Trusted_Connection = YES");</p> <p>Sqldataadapter mycommand = new sqldataadapter (selectcmd, myconnection);</p> <p>DataSet DS = New Dataset ();</p> <p>MyCommand.Fill (DS, "Recording");</p> <p>Recordingselect.datasource = ds;</p> <p>Recordingselect.DataTextField = "Title";</p> <p>Recordingselect.datavaluefield = "id";</p> <p>Recordingselect.database ();</p> <p>}</p> <p>Void Submitbtn_Click (Object Sender, Eventargs E)</p> <p>{</p> <p>String selectcmd = string.format ("Select * from track where recordingid = {0} Order By ID", (String) RecordingSelect.SelectedItem.Value);</p> <p>SqlConnection MyConnection = New SqlConnection ("Server = (local); Database = Recordings; Trusted_Connection = YES");</p> <p>Sqldataadapter mycommand = new sqldataadapter (selectcmd, myconnection);</p> <p>DataSet DS = New Dataset (); MyCommand.Fill (DS, "TRACK");</p> <p>MyDataGrid.dataSource = DS;</p> <p>MyDataGrid.databind ();</p> <p>}</p> <p></ script></p> <p></ hEAD></p> <p><body></p> <p><form id = "start" method = "post" runat = "server"></p> <p><h3> Recordings </ h3></p> <p>SELECT A Recording: <br /></p> <p><ask: DropDownList ID = "RecordingSelect" runat = "server" /></p> <p><asp: button runat = "server" text = "submit" onclick = "submitbtn_click" /></p> <p><p /></p> <p><ask: DATAGRID ID = "MyDataGrid" runat = "server" width = "700" backcolor = "# ccccff" bordercolor = "black" showfooter = "false" cellpadding = "3" cellspacing = "0" font-name = " Verdana "font-size =" 8pt "Headerstyle-backcolor =" # aaaadd "enableViewState =" false "/></p> <p></ form></p> <p></ body></p> <p></ html></p> <p>This implementation file contains three roles of models, views, and controllers, but does not split them into different files or classes. The view object is implemented with an HTML, with a data binding control to display data from the DataSet returned from the database. Model roles are implemented in page_load and subsmitbtn_click functions. The controller role does not have an explicit implementation, but is implicitly implemented by ASP.NET. When the program runs, when the user issues a page request, the page will update the user's selection.</p> <p>The MVC mode describes this implementation is a passive implementation mechanism, and the ASP.NET acts as the role of the controller in the execution, but the programmer must add the specific event processing method to the event's response function. As in this example, the controller calls the Page_Load function before the page is loaded and executes the code when the user clicks on the Submit button and executes.</p> <p>This type of implementation is very straightforward, and it can be a good method when the application is small and not modified often, but if you appear in some cases, you may Start considering modifying this implementation:</p> <p>Make the programmed work parallel and reduce the likelihood of this result. In order to increase the parallelism of the work, improve efficiency, you may want to write different people to write code and model code and try to reduce the likelihood of this work mode. For example: When all the code is in a file, then a programmer may inadvertently modify the code accessed inadvertent when changing the DataGrid display format. This error is difficult to discover until the page is compiled, and it will appear. .</p> <p>Reuse your data access code in other pages. In this single file implementation, in addition to copying code, there is no other method to be reused. Copy code is difficult to be maintained, because once the code changes, you must modify all pages. In order to avoid the occurrence of these conditions, ASP.NET introduces a code-behind mechanism. Reconstructing with code separation mechanism</p> <p>The code separation mechanism in Microsoft Visual Studio .NET makes the code from the code layer and the code of the model and the code of the controller can be easily separated. Each ASP.NET page has a mechanism that enables it to call the method, 谝 谝 鲇肫 浞 氲 氲 惺 惺 帧 u 址 址 褂 褂 鹄 鹄 鹄 5 址 址 址肰 ISUAL Studio .NET Some other features are jointly completed development. For example, when you use the code separation mechanism to develop your page, you can use the IntelliSense Technology to display a list of available methods to be programmed. The intelligent perception technology cannot be used in the .aspx page.</p> <p>The following example is the implementation of the above example utilizes the code separation mechanism.</p> <p>View part:</p> <p>The code of the view layer is now implemented in a separate file. Solution.aspx:</p> <p><% @ Page language = "c #" codebehind = "soliion.aspx.cs" autoeventwireup = "false" inherits = "solution"%></p> <p><html></p> <p><HEAD></p> <p><title> Solution </ Title></p> <p></ hEAD></p> <p><body></p> <p><form id = "solution" method = "post" runat = "server"></p> <p><h3> Recordings </ h3></p> <p>SELECT A Recording: <br/></p> <p><ask: DropDownList ID = "RecordingSelect" runat = "server" /></p> <p><ask: button id = "submit" runat = "server" text = "submit"</p> <p>EnableViewState = "false" /></p> <p><p /></p> <p><ask: DataGrid ID = "MyDataGrid" runat = "server" width = "700"</p> <p>Backcolor = "# ccccff" bordercolor = "black" showfooter = "false"</p> <p>Cellpadding = "3" cellspacing = "0" font-name = "verdana" font-size = "8pt"</p> <p>Headerstyle-backcolor = "# aaaadd" enableViewState = "false" /></p> <p></ form></p> <p></ body></p> <p></ html></p> <p>Most of the code is the same as the code of the previous solution. The main difference is the first line:</p> <p><% @ Page language = "c #" codebehind = "solution.aspx.cs" autoeventwireup = "false" inherits = "solution"%> This line tells the ASP.NET execution environment, this page's specific implementation mechanism is in a separate class in. Because this page is independent, this page does not need to do any changes if the code of data accesses changes. Similarly, some designers can also change this page of the page without causing an error in any data access. Model and controller part: The second part of this solution is hidden background code:</p> <p>Using system;</p> <p>Using system.data;</p> <p>Using system.data.sqlclient;</p> <p>Public Class Solution: System.Web.ui.page</p> <p>{</p> <p>Protected system.Web.ui.WebControls.button submit;</p> <p>Protected system.Web.ui.WebControls.DataGrid mydatagrid;</p> <p>Protected system.Web.ui.webcontrols.dropdownlist recordingselect;</p> <p>Private Void Page_Load (Object Sender, System.EventArgs E)</p> <p>{</p> <p>IF (! ispostback)</p> <p>{</p> <p>String selectcmd = "select * from recording";</p> <p>SqlConnection MyConnection = New SqlConnection ("Server = (local); Database = Recordings; Trusted_Connection = YES");</p> <p>Sqldataadapter mycommand = new sqldataadapter (selectcmd, myconnection);</p> <p>DataSet DS = New Dataset ();</p> <p>MyCommand.Fill (DS, "Recording");</p> <p>Recordingselect.datasource = ds;</p> <p>Recordingselect.DataTextField = "Title";</p> <p>Recordingselect.datavaluefield = "id";</p> <p>Recordingselect.database ();</p> <p>}</p> <p>}</p> <p>Void Submitbtn_Click (Object Sender, Eventargs E)</p> <p>{</p> <p>String selectcmd = string.format ("Select * from track where recordingid = {0} Order By ID", (String) RecordingSelect.SelectedItem.Value);</p> <p>SqlConnection MyConnection = New SqlConnection ("Server = (local); Database = Recordings; Trusted_Connection = YES");</p> <p>Sqldataadapter mycommand = new sqldataadapter (selectcmd, myconnection);</p> <p>DataSet DS = New Dataset ();</p> <p>MyCommand.fill (DS, "Track");</p> <p>MyDataGrid.dataSource = DS; mydatagrid.databind ();</p> <p>}</p> <p>#Region Web Form Designer Generated Code</p> <p>Override protected void oninit (Eventargs E)</p> <p>{</p> <p>//</p> <p>// Codegen: This Call is Required by The ASP.NET Web Form Designer.</p> <p>//</p> <p>InitializationComponent ();</p> <p>Base.onit (E);</p> <p>}</p> <p>/// <summary></p> <p>/// Required Method for Designer Support - Do Not Modify</p> <p>/// The contents of this method with the code editor.</p> <p>/// </ summary></p> <p>Private vidinitiRizeComponent ()</p> <p>{</p> <p>This.Submit.Click = new system.eventhandler (this.submitbtn_click);</p> <p>This.Load = New System.EventHandler (this.page_load);</p> <p>}</p> <p>#ndregion</p> <p>}</p> <p>Here will move the code from the previous implementation method to a file in its own file. The views and model controllers are connected to a whole through some mechanisms. If the member variables in this class are the same name as the control used in the Solution.aspx file. Another must be displayed that how the controller connects the behavior to the events thereafter. In this example, the InitializationComponent function is connected to two events. The first one connects the LOAD event with the Page_Load function, the second is the Click event, call the submitbtn_click function when the Submit button is clicked.</p> <p>The code separation is an excellent mechanism that separates the view part and the model and controller part. But when you want to remove the code from the isolated background to other pages, it may be insufficient. Technically, the code reuse behind the page is feasible, but as you need to share the increase in the page, it is difficult to connect the page with the background code. Model - View - Controller Separation In order to solve the problem left by the above, you must separate the model to the controller role. The implementation code of the view is the same as the front portion. The code example below makes the model role only depends on the database without including any code-dependent code.</p> <p>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;} The current code only depends only on the database, this class It is a channel of an excellent database that holds the SQL statement used to access the table or view, and the other code calls some methods to complete The interaction of the database. Controller This reconstruction manner utilizes the code hidden mechanism, and the controller is responsible for the control of the event and method in the case where the model portion responsible for data access is relatively independent. The task of the model is clear, it only returns a DataSet object. This implementation is like view code, and does not rely on how the data is returned from the database.</p> <p>Using system;</p> <p>Using system.data;</p> <p>Using system.collections;</p> <p>Using system.Web.ui.webcontrols;</p> <p>Public Class Solution: System.Web.ui.page</p> <p>{</p> <p>Protected system.Web.ui.WebControls.button submit;</p> <p>Protected system.Web.ui.WebControls.DataGrid mydatagrid;</p> <p>Protected system.Web.ui.webcontrols.dropdownlist recordingselect;</p> <p>Private Void Page_Load (Object Sender, System.EventArgs E)</p> <p>{</p> <p>IF (! ispostback)</p> <p>{</p> <p>DataSet DS = DatabaseGateway.getRecordings ();</p> <p>Recordingselect.datasource = DS; RecordingSelect.DataTfield = "Title";</p> <p>Recordingselect.datavaluefield = "id";</p> <p>Recordingselect.database ();</p> <p>}</p> <p>}</p> <p>Void Submitbtn_Click (Object Sender, Eventargs E)</p> <p>{</p> <p>DataSet DS = DatabaseGateway.gettracks (String) RecordingSelect.SelectedItem.Value;</p> <p>MyDataGrid.dataSource = DS;</p> <p>MyDataGrid.databind ();</p> <p>} #Region Web Form Designer Generated Code</p> <p>Override protected void oninit (Eventargs E)</p> <p>{</p> <p>//</p> <p>// Codegen: This Call is Required by The ASP.NET Web Form Designer.</p> <p>//</p> <p>InitializationComponent ();</p> <p>Base.onit (E);</p> <p>}</p> <p>/// <summary></p> <p>/// Required Method for Designer Support - Do Not Modify</p> <p>/// The contents of this method with the code editor.</p> <p>/// </ summary></p> <p>Private vidinitiRizeComponent ()</p> <p>{</p> <p>This.Submit.Click = new system.eventhandler (this.submitbtn_click);</p> <p>This.Load = New System.EventHandler (this.page_load);</p> <p>}</p> <p>#ndregion</p> <p>}</p> <p>test</p> <p>Separating the model portion from the ASP.NET environment enables the model portion to be tested more easily. In the ASP.NET environment, you must test a lot at the same time, such as whether the HTML code is correct, and reading the HTML code is very bored. Separate the model part so you can make a separate unit test on the model portion. The following is an example of unit testing of the model section below NUnit (http://nunit.org).</p> <p>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 "]. Rount);} [test] public void tracks2345Query () {DataSet DS = DatabaseGateway.gettracks (" 2345 "); assertion.assertequals (3 , ds.tables ["track"]. rount);} [test] public void recordings () {dataset ds = DatabaseGateway.getRecordings (); assertion.assertequals (4, ds.tables ["replaording"]. Rows .Count); dataable recording = ds.tables ["replaording"]; assertion.assertequals (4, replaording.rows.count); DATAROW FIRSTROW = Recording.Rows [0]; string title = (string) FIRSTROW ["Title" ]; Assertion.assertequals ("up", title.trim ());}} Conclusion: The MVC mode is implemented in ASP.NET has the following advantages and disadvantages: advantage: can reduce dependence. The programmer can implement all the code in an ASP.NET page. Single page implementation, for some small and long-lived programs are applicable. However, if you want to share the code between the increasing pages, it is very effective. Ability to reduce the copy of the code. The GetRecordings and GetTracks methods in the Databasegateway class can be used directly by other pages, reducing the case where the code must be copied to different pages. Ability to separate the responsibility of different people. Modifying the appearance of the page and the technique used by the code to modify the data accessed is different, and the model is separated from the view to the work of experts responsible for different work.</p> <p>Make performance optimization may be possible to divide different classes into different classes to make performance optimization. In the previous example, data is read from the database since each request page is requested. Therefore, the data can be cached in some case, thereby increasing the performance of the entire program. If you don't separate the code, you cannot do this. Easy testivity The model is separated from the view into unit testing in an ASP.NET environment. Disadvantages: Increase the number and complexity of the code. This example adds new files and code based on the implementation of the earlier single page, and the maintenance overhead is added in invisible. Once the system is modified, the code for all three roles will be modified. In some cases, modifications in a file are more convenient than modifying in some files. So when considering whether you use the MVC mode. This additional overhead must be calculated, for some small programs, this overhead is not worth it.</p></div><div class="text-center mt-3 text-grey"> 转载请注明原文地址:https://www.9cbs.com/read-81552.html</div><div class="plugin d-flex justify-content-center mt-3"></div><hr><div class="row"><div class="col-lg-12 text-muted mt-2"><i class="icon-tags mr-2"></i><span class="badge border border-secondary mr-2"><h2 class="h6 mb-0 small"><a class="text-secondary" href="tag-2.html">9cbs</a></h2></span></div></div></div></div><div class="card card-postlist border-white shadow"><div class="card-body"><div class="card-title"><div class="d-flex justify-content-between"><div><b>New Post</b>(<span class="posts">0</span>) </div><div></div></div></div><ul class="postlist list-unstyled"> </ul></div></div><div class="d-none threadlist"><input type="checkbox" name="modtid" value="81552" checked /></div></div></div></div></div><footer class="text-muted small bg-dark py-4 mt-3" id="footer"><div class="container"><div class="row"><div class="col">CopyRight © 2020 All Rights Reserved </div><div class="col text-right">Processed: <b>0.194</b>, SQL: <b>9</b></div></div></div></footer><script src="./lang/en-us/lang.js?2.2.0"></script><script src="view/js/jquery.min.js?2.2.0"></script><script src="view/js/popper.min.js?2.2.0"></script><script src="view/js/bootstrap.min.js?2.2.0"></script><script src="view/js/xiuno.js?2.2.0"></script><script src="view/js/bootstrap-plugin.js?2.2.0"></script><script src="view/js/async.min.js?2.2.0"></script><script src="view/js/form.js?2.2.0"></script><script> var debug = DEBUG = 0; var url_rewrite_on = 1; var url_path = './'; var forumarr = {"1":"Tech"}; var fid = 1; var uid = 0; var gid = 0; xn.options.water_image_url = 'view/img/water-small.png'; </script><script src="view/js/wellcms.js?2.2.0"></script><a class="scroll-to-top rounded" href="javascript:void(0);"><i class="icon-angle-up"></i></a><a class="scroll-to-bottom rounded" href="javascript:void(0);" style="display: inline;"><i class="icon-angle-down"></i></a></body></html><script> var forum_url = 'list-1.html'; var safe_token = 'OfILuu3RRe32rXoxGlE6AtGNStHZJLxswUBZ9S0uTxsyFCHiwvL7Mj8vxCUJrP0rcGT6ERwGszCBsUnr'; var body = $('body'); body.on('submit', '#form', function() { var jthis = $(this); var jsubmit = jthis.find('#submit'); jthis.reset(); jsubmit.button('loading'); var postdata = jthis.serializeObject(); $.xpost(jthis.attr('action'), postdata, function(code, message) { if(code == 0) { location.reload(); } else { $.alert(message); jsubmit.button('reset'); } }); return false; }); function resize_image() { var jmessagelist = $('div.message'); var first_width = jmessagelist.width(); jmessagelist.each(function() { var jdiv = $(this); var maxwidth = jdiv.attr('isfirst') ? first_width : jdiv.width(); var jmessage_width = Math.min(jdiv.width(), maxwidth); jdiv.find('img, embed, iframe, video').each(function() { var jimg = $(this); var img_width = this.org_width; var img_height = this.org_height; if(!img_width) { var img_width = jimg.attr('width'); var img_height = jimg.attr('height'); this.org_width = img_width; this.org_height = img_height; } if(img_width > jmessage_width) { if(this.tagName == 'IMG') { jimg.width(jmessage_width); jimg.css('height', 'auto'); jimg.css('cursor', 'pointer'); jimg.on('click', function() { }); } else { jimg.width(jmessage_width); var height = (img_height / img_width) * jimg.width(); jimg.height(height); } } }); }); } function resize_table() { $('div.message').each(function() { var jdiv = $(this); jdiv.find('table').addClass('table').wrap('<div class="table-responsive"></div>'); }); } $(function() { resize_image(); resize_table(); $(window).on('resize', resize_image); }); var jmessage = $('#message'); jmessage.on('focus', function() {if(jmessage.t) { clearTimeout(jmessage.t); jmessage.t = null; } jmessage.css('height', '6rem'); }); jmessage.on('blur', function() {jmessage.t = setTimeout(function() { jmessage.css('height', '2.5rem');}, 1000); }); $('#nav li[data-active="fid-1"]').addClass('active'); </script>