精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

ASP.NET MVC并不僅僅只是LINQ To SQL

開發 后端
很多ASP.NET的教程中的示例代碼使用的數據訪問方法是Linq to SQL或是Entity Framework,本文就講述了使用ADO.NET作為數據訪問層來實現一個典型的增刪查改程序,這里只是講述各個層所扮演的角色,但是不會深入到代碼的細節中。

ASP.NET MVC是微軟官方提供的MVC模式編寫ASP.NET Web應用程序的一個框架,不久前微軟發布了ASP.NET MVC 2 RC 2新版本增強了對HTML的控制,同時對Area特性也有一定的增強,而在不久之后也將會支持Visual Studio 2010。

這里我們只是講述各個層所扮演的角色,但是不會深入到代碼的細節中。N-Layer構架的三個關鍵層分別為:業務對象層,業務邏輯層和數據訪問層。而其數據訪問層會幾乎不加改變的包含在本文的MVC項目中,Spaanjaar的文件詳細描述了各個層是如何組織的。

首先,我們來看Imar提供的程序,這是一個具有典型增刪查改的程序,這個程序允許用戶管理聯系人,包括聯系人的地址,電話,email。它能增,刪,查,改任何實體。

Imar提供的程序

程序內包括的實體有:ContactPersons,PhoneNumbers,AddressesEmailAddresses.他們都隸屬于程序的業務對象(BO)層。上述的每一個類都包含可以獲取或者賦值的屬性,但并不包含任何方法。而所有方法存放于業務邏輯層(BLL)中的對應類中。在業務對象層和業務邏輯層的實體和實體manger是一對一的關系,在業務邏輯層中類包含的方法都會返回業務對象層(BO)的實例,或是實例集合,或者保存實例(更新或是添加),或是刪除實例。業務邏輯層(BLL)中也可以包含一些業務規則驗證,安全性檢查的代碼。但在本篇文章為了簡便起見,就不添加這些了。如果你對業務規則和安全性有興趣的話,可以去看Imar文章的6partseries。

最后一層是數據訪問層(DAL),同樣,DAL層的類也和業務邏輯層(BLL)內的類有著一對一的關系,在BLL層的類中會調用相關DAL層中的方法。而在這些層中,只有DAL層需要知道利用什么技術(linq,entityframework..)保存業務實體。在本例中,使用SqlServerExpress數據庫和ADO.NET。而這樣分層的思想是如果你需要更換數據源(XML,oracle,更或者是WebService甚至是LinqtoSql或者其他ORM框架),因為DAL層給BLL層暴漏的方法的簽名是一致的,所以只需要更換DAL層即可。而為了保證所有DAL的實現有著同樣的簽名,則利用接口即可。但我想或許是未來帖子中討論的話題了吧。

MVC構架

簡單的說,M代表Model,也是包含BO,BLL,DAL的地方,V代表View,也是UI相關開發的部分,或者說是用戶看到的部分,C是Controller的簡寫,也是控制用戶請求與程序回復的部分。如果用戶點擊了一個指向特定地址的按鈕,請求會和Controller的Action(類的方法)進行匹配,而Action負責處理請求,并返回響應。通常情況下是一個新的View,或者是更新現有的View。

下面用VisualStudio創建一個MVC應用程序并刪除默認的View和Controller,然后將Imar的程序中的Bo,Bll和DAL復制到這個MVC程序的Model內,我還復制了響應的數據庫文件和Style.css。

創建一個MVC應用程序

我還做了一些其他的修改,把數據庫連接字符串添加到Web.Config中。除此之外,我還將復制過來的代碼的命名空間做了響應的調整并把DAL層的代碼升級到了3.0.雖然這并不是必須的。做完這些,我按Ctrl+Shift+F5來測試是否編譯成功。

Controller

添加4個Controller(VisualStudio附帶的默認Controller已經被刪除),和四個實體類相匹配。它們分別為:ContactController,PhoneController,AddressControllerandEmailController。

四個實體類

每個Controller都含有四個Action:List,Add,Edit,andDelete。首先需要在Global.exe中為這些Action注冊這些路由。

  1. public static void RegisterRoutes(RouteCollection routes)  
  2. {  
  3.   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
  4.  
  5.   routes.MapRoute(  
  6.       "Default",                                                
  7.       "{controller}/{action}/{id}",                             
  8.       new { controller = "Contact"action = "List"id = "" }    
  9.   );  

默認的View會顯示所有聯系人,BLL層中的ContactPersonManager類內的GetList()方法會獲取所有聯系人的數據,響應的List()Action代碼如下:

  1. public ActionResult List()  
  2. {  
  3.   var model = ContactPersonManager.GetList();  
  4.   return View(model);  

#p#

強類型View

整個實例代碼中,我都會使用強類型的View,因為這樣不僅可以使用intellisense(智能提示)的好處,還不必依賴于使用String作為索引值的ViewData。為了讓代碼更加有序,我添加了一些命名空間到web.config中的<namespaces>節點,這些都是我用來替換Imar代碼的方式:

  1. <namespaces> 
  2. <add namespace="System.Web.Mvc"/> 
  3. <add namespace="System.Web.Mvc.Ajax"/> 
  4. <add namespace="System.Web.Mvc.Html"/> 
  5. <add namespace="System.Web.Routing"/> 
  6. <add namespace="System.Linq"/> 
  7. <add namespace="System.Collections.Generic"/> 
  8. <add namespace="ContactManagerMVC.Views.ViewModels"/> 
  9. <add namespace="ContactManagerMVC.Models.BusinessObject"/> 
  10. <add namespace="ContactManagerMVC.Models.BusinessObject.Collections"/> 
  11. <add namespace="ContactManagerMVC.Models.BusinessLogic"/> 
  12. <add namespace="ContactManagerMVC.Models.DataAccess"/> 
  13. <add namespace="ContactManagerMVC.Models.Enums"/> 
  14. </namespaces> 

上面代碼意味著我可以在程序的任何地方訪問上述命名空間。上面GetList()方法返回的類型是ContactPersonList,這個類型是ContactPerson對象的集合,在顯示List的View中的Page聲明如下:

  1. <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactPersonList>" %> 

我想你已經注意到了我使用了MasterPage,利用MasterPage,我借用了從Imar實例代碼中的Css文件。用于顯示ContactPerson對象的HTML如下:

  1. <table class="table"> 
  2.     <tr> 
  3.       <th scope="col">Id</th> 
  4.       <th scope="col">Full Name</th> 
  5.       <th scope="col">Date of Birth</th> 
  6.       <th scope="col">Type</th> 
  7.       <th scope="col">&nbsp;</th> 
  8.       <th scope="col">&nbsp;</th> 
  9.       <th scope="col">&nbsp;</th> 
  10.       <th scope="col">&nbsp;</th> 
  11.       <th scope="col">&nbsp;</th>    
  12.     </tr> 
  13.     <%  
  14.       if (Model != null)  
  15.       {  
  16.         foreach (var person in Model)  
  17.         {%> 
  18.     <tr> 
  19.       <td><%= person.Id %></td> 
  20.       <td><%= person.FullName %></td> 
  21.       <td><%= person.DateOfBirth.ToString("d") %></td> 
  22.       <td><%= person.Type %></td> 
  23.       <td title="address/list" class="link">Addresses</td> 
  24.       <td title="email/list" class="link">Email</td> 
  25.       <td title="phone/list" class="link">Phone Numbers</td> 
  26.       <td title="contact/edit" class="link">Edit</td> 
  27.       <td title="contact/delete" class="link">Delete</td> 
  28.     </tr> 
  29.     <%  
  30.         }  
  31.       }else{%> 
  32.     <tr> 
  33.       <td colspan="9">No Contacts Yet</td> 
  34.     </tr>    
  35.      <% }%> 
  36.   </table> 

 

我想你已經能發現強類型View的好處了吧,Model的類型是ContactPersonList,所以你可以任意使用ContactPersonList的屬性而不用強制轉換,而強制轉換錯誤只有在運行時才能被發現,所以這樣省了不少事。

在做Html時,我小小的作弊了一下,我本可以使用vs對list自動生成的view,但我沒有。因為我需要和Imar的css文件相匹配的html.所以我運行了imar的程序,在瀏覽器中查看源代碼,并把生成的html復制下來,imar使用GridView來生成列表,所以CSS會在運行時嵌入到html代碼中。我將這些css代碼移到一個外部的css文件中。并給<th>和<td>元素添加了一些額外樣式,你可以在代碼的下載鏈接中找到。

我還未一些表格的單元格添加了title屬性。這些包含了訪問其他action的鏈接。我希望用戶在瀏覽電話本或者編輯或者刪除電話本時頁面不會postback,換句話說,我希望我的網站是ajax的。而title屬性就發揮作用了。而“。link”這個css選擇符可以讓普通的文本看起來像超鏈接,也就是有下劃線和鼠標hover時出現小手。#p#

JQuery Ajax

在我們深入實現ajax功能的相關代碼之前,下面3行代碼是需要加入到html中:

  1. <input type="button" id="addContact" name="addContact" value="Add Contact" /> 
  2. <div id="details"></div> 
  3. <div id="dialog" title="Confirmation Required">Are you sure about this?</div> 

第一行代碼的作用是一個允許用戶添加新聯系人的按鈕,第二行代碼是一個空div,方便后面顯示信息,第三行代碼是jQuerymodal提示驗證對話框的一部分,用于提示用戶是否刪除一條記錄。

還需要在頁面中添加3個js文件,第一個是主要的jQuery文件,其他兩個分別是jQueryUI的核心js,以及datepicker和modaldialog部分的JS:

  1. <script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script> 
  2. <script src="../../Scripts/ui.core.min.js" type="text/javascript"></script> 
  3. <script src="../../Scripts/jquery-ui.min.js" type="text/javascript"></script> 

下面是我們生成后的列表顯示視圖以及完全的JS代碼:

列表顯示視圖以及完全的JS代碼

 

  1. <script type="text/javascript"> 
  2.   $(function() {  
  3.     // row colours  
  4.     $('tr:even').css('background-color', '#EFF3FB');  
  5.     $('tr:odd').css('background-color', '#FFFFFF');  
  6.     // selected row managment  
  7.     $('tr').click(function() {  
  8.       $('tr').each(function() {  
  9.         $(this).removeClass('SelectedRowStyle');  
  10.       });  
  11.       $(this).addClass('SelectedRowStyle');  
  12.     });   
  13.     // hide the dialog div  
  14.     $('#dialog').hide();  
  15.     // set up ajax to prevent caching of results in IE  
  16.     $.ajaxSetup({ cache: false });  
  17.     // add an onclick handler to items with the "link" css class  
  18.     $('.link').live('click', function(event) {  
  19.       var id = $.trim($('td:first', $(this).parents('tr')).text());  
  20.       var loc = $(this).attr('title');  
  21.       // check to ensure the link is not a delete link  
  22.       if (loc.lastIndexOf('delete') == -1) {  
  23.         $.get(loc + '/' + id, function(data) {  
  24.           $('#details').html(data);  
  25.         });  
  26.       // if it is, show the modal dialog     
  27.       } else {  
  28.         $('#dialog').dialog({  
  29.           buttons: {  
  30.             'Confirm': function() {  
  31.               window.location.href = loc + '/' + id;  
  32.             },  
  33.             'Cancel': function() {  
  34.               $(this).dialog('close');  
  35.             }  
  36.           }  
  37.         });   
  38.         $('#dialog').dialog('open');  
  39.         }  
  40.       });   
  41.       // add an onclick event handler to the add contact button  
  42.       $('#addContact').click(function() {  
  43.         $.get('Contact/Add', function(data) {  
  44.           $('#details').html(data);  
  45.         });  
  46.       });   
  47.     });  
  48. </script> 

 

上面代碼看起來讓人望而卻步,但實際上,使用jQuery,這非常簡單。并且在上面代碼中我多處加入了注釋,代碼一開始是用js代碼是替換了數據源控件默認呈現出來的隔行變色的顏色。然后我加入了使點擊行點擊時可以變色的代碼。然后下面的代碼是防止IE對頁面進行緩存。如果不禁止了IE緩存,你會為執行編輯或者刪除以后,數據庫改變了但頁面卻沒有發生變化而撞墻的。

接下來的代碼更有趣了,依靠live()方法可以確$選擇器中所有匹配的元素都被附加了相應的事件,無論元素當前是否存在于頁面中。比如說,當你點擊了Addresses鏈接,相應的結果就會在另一個表中出現:

點擊Addresses鏈接的結果

上圖中可以看出表中包含編輯和刪除鏈接,如果不使用live()方法,相應的鏈接就不會被附加事件。所有具有class為link的元素都會被委派上click事件。這個事件會首先獲取到當前條目的id.以ContactPerson表為例,這個id就是ContactPersonId.在相應的子表中,則id會是電話號碼或者是email地址。這些都是需要傳遞給controlleraction作為參數進行編輯,刪除,或者顯示的。

你現在可以看出為什么我為每個單元格加上title屬性了吧。title屬性包含相關的route信息,而完全的url則把id附加到route作為url.然后,上面js會做一個檢查,來看route信息內是否包含delete,如果包含delelte,則彈出一個對話框來提示用戶是否要刪除???,是不是很簡單?最后,代碼會為添加聯系人按鈕添加click事件。 #p#

添加聯系人以及自定義ViewModels

使用添加一條記錄時,通常的做法是提供一個包含一系列輸入框的form.對于ContactPerson類的大多屬性來說,都是可以直接賦值的,比如:姓,名字,生日。但是其中有一個屬性卻不能直接賦值--Type屬性,這個值是從PersonType.cs(朋友,同事等)中的枚舉類型中選擇出來的.這意味著用戶只能從有限的幾種選項中選擇一種??梢杂肈ropDwonList來實現,但是ContactPerson對象并不包含枚舉類型的所有選項,所以我們只能提供一個自定義版本的ContactPerson類傳遞給View。這也是為什么要用到自定義ViewModel。

我看過很多關于在程序的哪里放置ViewModels的討論,有些人認為自定義ViewModels是Model的一部分,但是我認為它和View緊密相關,ViewModels并不是MVC程序必不可少的一部分,也不能服用,所以它不應該放到Model中區。我把所有的ViewModel放入一個創建的ViewModel文件夾下,ContactPersonViewModel.cs的源代碼如下:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Web.Mvc;  
  4.  
  5. namespace ContactManagerMVC.Views.ViewModels  
  6. {  
  7.   public class ContactPersonViewModel  
  8.   {  
  9.     public int Id { get; set; }  
  10.     public string FirstName { get; set; }  
  11.     public string MiddleName { get; set; }  
  12.     public string LastName { get; set; }  
  13.     public DateTime DateOfBirth { get; set; }  
  14.     public IEnumerable<SelectListItem> Type { get; set; }  
  15.   }  

看上面類的最后一個屬性,我將這個type屬性設置成IEnumerable<SelectListItem>類型,這樣就可以將Type綁定到View中的Html.DropDownList了。

對應的,也要在Controller中添加2個action,第一個action使用AcceptVerbs(HttpVerbs.Get)標簽,第二個action使用AcceptVerbs(HttpVerbs.Post)標簽,第一個方法用于從服務器向客戶端傳值,第一個方法處理從form提交的數據。

上面第一個action的前幾行代碼將ContactType枚舉類型轉換成數組,數組中的每一個元素都是一個包含id和name屬性的匿名對象,id是枚舉值,Name是和對應枚舉匹配的constant值,ContactPersonViewModel然后進行初始化并且Type屬性被賦值相應的類型。我使用PartialView來添加聯系人和使用ContactPersonViewModel類型的強類型,對應View部分的代碼如下:

在最上面的代碼我使用了jQueryUI的Datepicker插件作為DateOfBirth輸入框的選擇方式,而DateOfBirth的第二個參數保證這個textbox在初始狀態下為空。此外,所有的輸入框對ContactPerson的對應屬性名相同,這是為了確保默認的modelbinder不出差錯,MVC還自動為ContactType枚舉進行綁定。

自動為ContactType枚舉進行綁定

負責響應Post請求的方法可以自動將Request.Form的值和ContactPerson對象的對應屬性進行匹配,然后調用BLL層的Save()方法,然后RedicrectToAction會讓頁面刷新最后調用List這個action。 #p#

編輯一個聯系人

我們在前面已經看到jQuery是如何調用Edit這個action并把被編輯人的id作為參數進行傳遞的了,然后id用于通過眾所周知的bll調用DAL從數據庫將聯系人的詳細信息取出來。

  1. <script type="text/javascript"> 
  2.   $(function() {  
  3.     $('#DateOfBirth').datepicker({dateFormat: 'yy/mm/dd'});  
  4.   });  
  5. </script> 
  6.  
  7. <% using (Html.BeginForm("Edit", "Contact", FormMethod.Post)) {%>   
  8.      <table> 
  9.         <tr> 
  10.           <td class="LabelCell">Name</td> 
  11.           <td><%= Html.TextBox("FirstName") %></td> 
  12.         </tr> 
  13.         <tr> 
  14.           <td class="LabelCell">Middle Name</td> 
  15.           <td><%= Html.TextBox("MiddleName") %></td> 
  16.         </tr> 
  17.         <tr> 
  18.           <td class="LabelCell">Last Name</td> 
  19.           <td><%= Html.TextBox("LastName") %></td> 
  20.         </tr> 
  21.         <tr> 
  22.           <td class="LabelCell">Date of Birth</td> 
  23.           <td><%= Html.TextBox("DateOfBirth", Model.DateOfBirth.ToString("yyyy/MM/dd")) %></td> 
  24.         </tr> 
  25.         <tr> 
  26.           <td class="LabelCell">Type</td> 
  27.           <td><%= Html.DropDownList("Type")%></td> 
  28.         </tr> 
  29.         <tr> 
  30.           <td class="LabelCell"><%= Html.Hidden("Id") %></td> 
  31.           <td><input type="submit" name="submit" id="submit" value="Save" /></td> 
  32.         </tr> 
  33.       </table> 
  34. <% } %> 

關鍵不同是DateOfBirth包含一個將生日信息轉換更容易識別的方式,還有在提交按鈕附近添加了一個Html.Hidden(),用于保存被編輯用戶的id。當然,form的action屬性肯定是和Add的View不同。在Form中可以加一個參數用于告訴Action是AddView還是EditView,這樣就能減少代碼的重復,但是在示例代碼中我還是把他們分成了不同的action,來讓職責劃分的更清晰一些。#p#

刪除一個聯系人

刪除action就簡單多了,并且不需要與之相關的View.僅僅是重新調用List這個action,被刪除的數據就不復存在了。上面代碼是我對BLL和DAL做出改變的地方,原來的ContactPersonManager.Delete()方法的參數是Person的實例,而在DAL中,只有id作為參數。我看不出傳遞整個對象給BLL,但BLL卻只傳遞對象的唯一ID給DAL的意義所在,所以我將BLL的代碼改成接受int類型的參數,這樣寫起來會更簡單。當刪除鏈接被點擊時,調用jQuery的confirmationmodaldialog:

調用jQuery的confirmationmodaldialog

如果點擊取消,則什么事也不發生,如果點擊確認,則鏈接就會指向響應的deleteaction。

管理集合

所有的集合--PhoneNumberList,EmailAddressLIst,AddressList被管理的方式如出一轍。所以,我僅僅挑選EmailAddressLIst作為示例來說明方法,你可以下載示例代碼來看其他部分。上面方法使用聯系人的id作為聯系人,并且返回一個自定義ViewModel—EmailAddressListViewModel.這也是將聯系人的id傳到View的方法:

  1. <script type="text/javascript"> 
  2.   $(function() {  
  3.     $('#add').click(function() {  
  4.       $.get('Email/Add/<%= Model.ContactPersonId %>', function(data) {  
  5.         $('#details').html(data);  
  6.       });  
  7.     });  
  8.   });  
  9. </script> 
  10. <table class="table"> 
  11.    <tr> 
  12.      <th scope="col">Contact Person Id</th> 
  13.      <th scope="col">Email</th> 
  14.      <th scope="col">Type</th> 
  15.      <th scope="col">&nbsp;</th> 
  16.      <th scope="col">&nbsp;</th> 
  17.    </tr> 
  18.    <%if(Model.EmailAddresses != null)  
  19.      {foreach (var email in Model.EmailAddresses) {%> 
  20.    <tr> 
  21.      <td><%= email.Id %></td> 
  22.      <td><%= email.Email %></td> 
  23.      <td><%= email.Type %></td> 
  24.      <td title="email/edit" class="link">Edit</td> 
  25.      <td title="email/delete" class="link">Delete</td> 
  26.    </tr> 
  27.         <%}  
  28.     }else  
  29.  {%> 
  30.    <tr> 
  31.      <td colspan="9">No email addresses for this contact</td> 
  32.    </tr> 
  33.  <%}%> 
  34. </table> 
  35. <input type="button" name="add" value="Add Email" id="add" /> 

你可以看出添加方法需要ContactPersonID作為參數,我們需要確??梢蕴砑有碌穆撓等说巾憫穆撓等肆斜?。編輯和刪除方法也是如此--id參數通過url傳遞到相關action.而所有的單元格都有title屬性,這樣就可以使用前面部署的live()方法:

  1. [AcceptVerbs(HttpVerbs.Get)]  
  2. public ActionResult Add(int id)  
  3. {  
  4.   var contactTypes = Enum.GetValues(typeof(ContactType))  
  5.     .Cast<ContactType>()  
  6.     .Select(c => new  
  7.     {  
  8.       Id = c,  
  9.       Name = c.ToString()  
  10.     });  
  11.   var model = new EmailAddressViewModel  
  12.                 {  
  13.                   ContactPersonId = id,  
  14.                   Type = new SelectList(contactTypes, "ID", "Name")  
  15.                 };  
  16.   return PartialView("Add", model);  
  17. }  
  18.  
  19.  
  20. [AcceptVerbs(HttpVerbs.Post)]  
  21. public ActionResult Add(EmailAddress emailAddress)  
  22. {  
  23.   emailAddress.Id = -1;  
  24.   EmailAddressManager.Save(emailAddress);  
  25.   return RedirectToAction("List", new {id = emailAddress.ContactPersonId});  

創建自定義ViewModel存在的目的是為了對現有的EmailAddress進行添加或編輯,這包括一些綁定IEnumerable<SelectListItem>集合到Typedropdown的屬性,上面兩個Add不同之處在于他們的返回不同,第一個返回partialview,第二個返回List這個action。

集合中的每一個選在在一開始都會將id設為-1,這是為了保證符合”Upsert”存儲過程的要求,因為Imar對于添加和刪除使用的是同一個存儲過程,如果不設置成-1,則當前新建的聯系人會更新掉數據庫中的聯系人。

上面jQuery代碼負責通過Ajax提交form.jQuery給htmlbutton(而不是inputtype=”submit”)附加事件,然后將頁面中的內容序列化并通過post請求發送到使用合適AcceptVerbs標簽修飾的名為add()的action。 #p#

編輯和刪除EmailAddress對象

編輯EmailAddress對象所涉及的action和前面提到的很相似,仍然是兩個action,一個用于處理get請求,另一個用于處理post請求:

  1. AcceptVerbs(HttpVerbs.Get)]  
  2. public ActionResult Edit(int id)  
  3. {  
  4.   var emailAddress = EmailAddressManager.GetItem(id);  
  5.   var contactTypes = Enum.GetValues(typeof(ContactType))  
  6.     .Cast<ContactType>()  
  7.     .Select(c => new  
  8.     {  
  9.       Id = c,  
  10.       Name = c.ToString()  
  11.     });  
  12.   var model = new EmailAddressViewModel  
  13.   {  
  14.     Type = new SelectList(contactTypes, "ID", "Name", emailAddress.Type),  
  15.     Email = emailAddress.Email,  
  16.     ContactPersonId = emailAddress.ContactPersonId,  
  17.     Id = emailAddress.Id  
  18.   };  
  19.   return View(model);  
  20. }  
  21.  
  22. [AcceptVerbs(HttpVerbs.Post)]  
  23. public ActionResult Edit(EmailAddress emailAddress)  
  24. {  
  25.   EmailAddressManager.Save(emailAddress);  
  26.   return RedirectToAction("List", "Email", new { id = emailAddress.ContactPersonId });  

 

下面的partialView代碼現在應該很熟悉了吧:

  1. <script type="text/javascript"> 
  2.   $(function() {  
  3.     $('#save').click(function() {  
  4.       $.ajax({  
  5.         type: "POST",  
  6.         url: $("#EditEmail").attr('action'),  
  7.         data: $("#EditEmail").serialize(),  
  8.         dataType: "text/plain",  
  9.         success: function(response) {  
  10.           $("#details").html(response);  
  11.         }  
  12.       });  
  13.     });  
  14.   });  
  15. </script> 
  16.  
  17. <% using(Html.BeginForm("Edit", "Email", FormMethod.Post, new { id = "EditEmail" })) {%> 
  18. <table class="table"> 
  19. <tr> 
  20.   <td>Email:</td> 
  21.   <td><%= Html.TextBox("Email")%></td> 
  22. </tr> 
  23. <tr> 
  24.   <td>Type:</td> 
  25.   <td><%= Html.DropDownList("Type") %></td> 
  26. </tr> 
  27. <tr> 
  28.   <td><%= Html.Hidden("ContactPersonId") %><%= Html.Hidden("Id") %></td> 
  29.   <td><input type="button" name="save" id="save" value="Save" /></td> 
  30. </tr> 
  31. </table> 

上面代碼仍然和AddView很像,除了包含EmailAddress.Id的html隱藏域,這是為了保證正確的email地址被更新,而Deleteaction就不用過多解釋了吧。

  1. public ActionResult Delete(int id)  
  2. {  
  3.   EmailAddressManager.Delete(id);  
  4.   return RedirectToAction("List", "Contact");  

總結

這篇練習的目的是為了證明ASP.NET MVC在沒有Linq To SQL和Entity framework的情況下依然可以很完美的使用。文章使用了現有分層結構良好的ASP.NET 2.0 form程序,還有可重用的businessObjects層,bussinesslogic層以及DataAccess層。而DAL層使用ADO.NET調用SQL Server的存儲過程來實現。

同時也展示了如何使用強類型的ViewModels和簡潔的jQuery來讓UI體驗更上一層。這個程序并不是完美的,也不是用于真實世界。程序中View部分,以及混合編輯和刪除的action都還有很大的空間可以重構提升,程序還缺少驗證用戶輸入的手段,所有的刪除操作都會返回頁面本身。而更好的情況應該是顯示刪除后用一個子表來顯示刪除后的內容,這需要將ContactPersonId作為參數傳遞到相關Action,這也是很好實現的。

文章轉自CareySon的博客,

原文地址:http://www.cnblogs.com/CareySon/archive/2010/03/03/1676891.html
 
 【編輯推薦】

  1. 淺談ASP.NET MVC中TempData的實現機制
  2. 詳解ASP.NET MVC 2中的Area特性
  3. 詳解ASP.NET MVC 2中強類型HTML輔助方法
  4. 淺析ASP.NET MVC中Controller與View數據傳遞
  5. 圖解ASP.NET MVC與WebForm的區別
責任編輯:王曉東 來源: 博客園
相關推薦

2019-03-01 10:42:10

折疊手機iPhone智能手機

2017-09-28 17:20:17

榮之聯DataZoohadoop

2023-06-06 07:42:10

參數類型函數

2016-05-13 19:05:24

2013-08-21 10:04:32

大數據Gartner

2009-11-28 20:08:20

谷歌ChromeWeb應用

2018-07-06 15:07:17

2011-02-13 09:17:02

ASP.NET

2011-04-13 13:49:50

ASP.NET網站優化

2009-09-10 14:02:08

LINQ ASP.NE

2009-07-31 12:43:59

ASP.NET MVC

2009-07-24 13:20:44

MVC框架ASP.NET

2016-05-10 10:15:54

2013-07-04 15:22:46

華為WLAN接入

2020-01-15 06:00:52

物聯網IOT大數據

2009-07-22 10:09:59

ASP.NET MVC

2009-07-23 15:44:39

ASP.NET MVC

2009-07-23 14:31:20

ASP.NET MVC

2009-07-22 13:24:24

ASP.NET MVC

2009-07-20 10:53:59

ASP.NET MVC
點贊
收藏

51CTO技術棧公眾號

亚洲成人黄色在线| 日产精品一区二区| 午夜伦欧美伦电影理论片| 精品国产一区二区三区四区vr| 精品无码一区二区三区的天堂| 久久五月天小说| 精品国产伦一区二区三区免费| 波多野结衣50连登视频| 成人免费一级片| 欧美在线影院| 欧美日韩免费观看一区二区三区| 国产一区一区三区| 四虎影院在线播放| 雨宫琴音一区二区在线| 亚洲色图第一页| 久久久久久久久久毛片| 欧美男男tv网站在线播放| 国产精品无码永久免费888| 高清视频在线观看一区| 中文字幕手机在线视频| 欧美精品一卡| 色噜噜亚洲精品中文字幕| 欧亚乱熟女一区二区在线| 成人h在线观看| 欧美日韩午夜剧场| 日韩成人三级视频| www在线观看播放免费视频日本| 91欧美一区二区| 爱情岛论坛亚洲入口| 在线观看国产精品视频| 国产精品日韩久久久| 欧美日韩成人精品| 97在线观看视频免费| 日本欧美韩国国产| 精品乱码亚洲一区二区不卡| 毛片毛片毛片毛| 亚洲第一影院| 欧美三级xxx| 欧美视频免费看欧美视频| 黄网站在线播放| 国产精品人人做人人爽人人添| 欧亚精品中文字幕| 久久午夜无码鲁丝片| 国产精品成人a在线观看| 国产一区二区动漫| 亚洲精品久久久久久宅男| 国产亚洲成av人片在线观看| 95精品视频在线| 国产欧美一区二区在线播放| 国产国语亲子伦亲子| 麻豆91小视频| 欧美国产激情18| 亚洲色偷偷综合亚洲av伊人| 一区二区三区国产好| 亚洲国产成人精品视频| av影院在线播放| 天天av天天翘| 麻豆成人av在线| 国产日产久久高清欧美一区| 日本黄色中文字幕| 日本aⅴ免费视频一区二区三区| 久久久精品一区| 男人av资源站| 亚洲综合激情在线| 日韩国产欧美精品一区二区三区| 中国免费黄色片| 日韩精品免费一区二区三区竹菊| 日韩av综合网站| 中文字幕丰满乱子伦无码专区| 亚洲人成网77777色在线播放| 亚洲欧美精品一区| 女人黄色一级片| 91精品亚洲| 亚洲热线99精品视频| 久久久久久亚洲中文字幕无码| 九色成人国产蝌蚪91| 国产亚洲精品美女| 婷婷社区五月天| 国产精品videossex久久发布| 欧美黑人xxxx| 日本熟女毛茸茸| 另类成人小视频在线| 成人自拍性视频| 神马久久久久久久久久| 国产欧美一区二区精品性色超碰| 亚洲激情一区二区| 欧美xxxx免费虐| 一本久久综合亚洲鲁鲁五月天| 午夜在线观看av| 男人的天堂免费在线视频| 色偷偷成人一区二区三区91 | 鲁鲁视频www一区二区| 成人亚洲综合天堂| 亚洲精品v日韩精品| 欧美女人性生活视频| 亚洲美女性囗交| 亚洲mmav| 精品久久久久久无| 国产伦精品一区二区三区视频女| 久久综合给合| 欧美日韩一级片在线观看| 天天综合成人网| 欧美丝袜美腿| 久久精品国产清自在天天线| 日韩av在线播放观看| 日韩国产欧美视频| 国产精品国产三级欧美二区| 国产网站在线播放| 夜夜嗨av一区二区三区| 久久国产色av免费观看| 久久天堂久久| 国产亚洲精品久久久久久777| 九九九免费视频| 综合视频在线| 欧美在线视频在线播放完整版免费观看 | 激情小说欧美色图| japanese国产精品| 午夜精品久久久99热福利| 91麻豆视频在线观看| 91女人视频在线观看| 无码人妻aⅴ一区二区三区日本| 亚洲美女尤物影院| 懂色av一区二区三区| 欧美午夜精品理论片| 国产精品一区二区三区av麻| 亚洲福利小视频| 久久精品一区二区三区四区五区| 久久先锋资源| 九九九九精品| 超免费在线视频| 日韩一级黄色大片| 成人信息集中地| 美美哒免费高清在线观看视频一区二区 | 一区二区三区四区激情| 手机在线看福利| 天堂久久午夜av| 日韩精品免费观看| 激情综合网五月婷婷| 国产高清精品网站| 91社在线播放| 亚洲综合伊人| 北条麻妃99精品青青久久| 中文字幕你懂的| 国产欧美精品在线观看| 老熟妇仑乱视频一区二区 | 精品少妇一区二区三区日产乱码| 蜜桃视频最新网址| 蜜桃视频第一区免费观看| 日韩高清dvd| 成人啊v在线| 在线观看中文字幕亚洲| 这里只有精品免费视频| 久久99精品久久久久婷婷| 日韩国产欧美精品| 国产私拍福利精品视频二区| 影音先锋日韩有码| 中文字幕视频一区二区| 国产精品乱人伦中文| 亚洲欧美在线精品| 天天综合网91| 99电影在线观看| 成全电影大全在线观看| 日韩精品欧美激情| 国产中文字幕视频| 国产精品乱人伦| 伊人av在线播放| 亚洲国产一区二区三区a毛片| 国产伦精品一区二区三区在线| 9999在线视频| 亚洲人成五月天| 一本大道伊人av久久综合| 中文字幕一区二区三区四区| 99九九精品视频| 亚洲精品色图| 无遮挡亚洲一区| 日皮视频在线观看| 亚洲精品在线免费播放| 欧美日韩一级黄色片| 国产精品久久久久国产精品日日 | 高清不卡一区| 97久久精品人人澡人人爽缅北| 日韩一二三四| 欧美剧情电影在线观看完整版免费励志电影 | 欧美福利在线| 蜜桃成人在线| 精品伊人久久| 国产91露脸中文字幕在线| 日本免费在线观看| 欧美成va人片在线观看| 国产熟妇一区二区三区四区| 成人免费在线视频| 中文成人无字幕乱码精品区| 青青国产91久久久久久| 91视频 - 88av| 欧美日韩国产传媒| 国产福利久久精品| 91亚洲精品| 亚洲午夜小视频| 99国产精品久久久久久久成人| 偷拍日韩校园综合在线| 国产精品丝袜一区二区| 久久免费午夜影院| 极品白嫩少妇无套内谢| 蜜桃av噜噜一区二区三区小说| 日韩精品在线观看av| 三区四区不卡| 鲁鲁狠狠狠7777一区二区| 试看120秒一区二区三区| 国产91在线播放| 青草在线视频在线观看| 在线一区二区日韩| 亚州男人的天堂| 欧美一区二区免费| 中文字幕一区二区免费| 香蕉影视欧美成人| 黄色香蕉视频在线观看| 国产视频一区二区在线观看| 久久国产劲爆∧v内射| 久久超碰97人人做人人爱| 久久久久久久久久久久久国产精品| 91精品亚洲| 亚洲综合av一区| 欧美成人一级| 国产免费一区二区三区香蕉精| 免费网站免费进入在线| 日韩激情片免费| 丰满肥臀噗嗤啊x99av| 欧美精品国产精品| 自拍偷拍第八页| 色偷偷久久一区二区三区| 成人免费a视频| 亚洲国产裸拍裸体视频在线观看乱了 | 91精品国产高清自在线| av免费在线免费| 久久精品国产成人| 黄色成年人视频在线观看| 一本色道久久88精品综合| 激情小说 在线视频| 精品亚洲aⅴ在线观看| 少妇一级淫片免费看| 精品免费99久久| 人妻夜夜爽天天爽| 精品久久久久久久久久久久久久久久久| 国产精品免费无遮挡| 欧美性欧美巨大黑白大战| 成人免费a视频| 色88888久久久久久影院按摩| 五月婷婷色丁香| 精品久久久久久久久中文字幕| 日产电影一区二区三区| 亚洲一区二区四区蜜桃| 国产一级片视频| 午夜不卡av在线| 少妇太紧太爽又黄又硬又爽 | 国产又粗又长视频| 337p亚洲精品色噜噜狠狠| 国产精品高潮呻吟AV无码| 777a∨成人精品桃花网| 国产乱淫av片免费| 日韩视频免费观看高清完整版在线观看 | 欧美日韩综合久久| 欧州一区二区三区| 成人在线视频电影| 欧美理伦片在线播放| 麻豆av福利av久久av| 国产一区二区观看| 一区二区视频在线观看| 午夜日韩在线| 无码精品a∨在线观看中文| 久久资源在线| 8x8x成人免费视频| 不卡一区二区在线| 真实乱视频国产免费观看| 欧美韩国日本不卡| 精品欧美一区二区久久久久| 婷婷成人综合网| 波多野结衣激情视频| 欧美精品aⅴ在线视频| 亚洲经典一区二区三区| 亚洲欧美国产日韩中文字幕| 亚洲乱亚洲乱妇| 午夜精品一区二区三区在线| 成人黄色免费短视频| 51国偷自产一区二区三区| 欧美顶级毛片在线播放| 亚洲欧美综合一区| 一本色道精品久久一区二区三区| 无人在线观看的免费高清视频| 国内成人精品2018免费看| 久久久国产精品无码| 国产精品私人影院| 日韩xxxxxxxxx| 欧美日本视频在线| 日韩一区二区三区不卡| 色av中文字幕一区| 涩涩涩视频在线观看| 91理论片午午论夜理片久久| 欧美一区 二区| 熟女熟妇伦久久影院毛片一区二区| 亚洲精品免费观看| 91精品国产三级| 久久久99精品免费观看| 黄色一级视频免费观看| 欧美午夜视频网站| 色婷婷av一区二区三区之红樱桃| 中文字幕精品久久| 国产精选在线| 国产玖玖精品视频| 亚洲视频分类| cao在线观看| 国内久久婷婷综合| jizz日本在线播放| 欧美日韩亚洲成人| 日本wwwxxxx| 精品少妇一区二区30p| 久久亚洲国产精品尤物| 久久精品日产第一区二区三区| 一区二区三区在线观看免费| 日日噜噜噜噜久久久精品毛片| 99精品欧美一区二区蜜桃免费| 极品美妇后花庭翘臀娇吟小说| 欧美亚洲国产一区二区三区va| 桃花色综合影院| 91精品国产99| 澳门久久精品| 牛人盗摄一区二区三区视频| 欧美 日韩 国产精品免费观看| 色婷婷.com| 国产精品免费看片| 成人一级免费视频| 亚洲欧美日韩视频一区| 蜜桃视频在线观看免费视频| 99视频在线| 欧美激情第二页| 无人码人妻一区二区三区免费| 日韩一区日韩二区| 中文字幕一区二区三区人妻四季| 亚洲天堂男人天堂女人天堂| 亚洲最大成人| 日韩av电影免费观看| 久久精品一区二区国产| 久久精品国产亚洲av麻豆| 精品日韩视频在线观看| 天天干天天摸天天操| 97视频在线观看网址| 久久久伦理片| 男女av免费观看| 国产午夜精品久久| 日批视频免费观看| 日韩在线视频导航| 欧美网站免费| 亚洲开发第一视频在线播放| 日本亚洲一区二区| 亚洲综合图片一区| 日韩欧美www| caoprom在线| 麻豆av一区二区| 奇米亚洲午夜久久精品| 欧美日韩国产一二三区| 欧美精品日日鲁夜夜添| а√中文在线8| 精品无人区一区二区三区| 销魂美女一区二区三区视频在线| 九九精品久久久| 亚洲欧美一区二区三区国产精品| 亚洲精品国产精| 国产91精品青草社区| 精品国产日韩欧美| 一级黄色片国产| 亚洲图片一区二区| 九一国产在线| 91影院在线免费观看视频| 国产一区日韩一区| aa片在线观看视频在线播放| 91国偷自产一区二区开放时间| 午夜伦理在线| 国产精品初高中精品久久| 久久一区激情| 九九视频免费在线观看| 亚洲精品短视频| 亚洲精品第一| 国产91在线免费| 亚洲欧洲综合另类| 亚洲日本在线播放| 国产日韩欧美夫妻视频在线观看| 欧美三级视频| 国产馆在线观看| 亚洲第一福利视频| 国产乱子精品一区二区在线观看| 18视频在线观看娇喘| 91丨九色丨黑人外教| 国产一区二区三区三州| 97国产精品人人爽人人做| 成人写真视频| 黄色片视频免费观看| 欧美日韩不卡在线| 超碰资源在线| 亚洲中文字幕无码一区二区三区| 久久久亚洲高清| 黄色小视频免费在线观看|