现在的位置: 首页 > 综合 > 正文

通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用

2011年12月17日 ⁄ 综合 ⁄ 共 3871字 ⁄ 字号 评论关闭
文章目录

较之面向最终消费者的网站,企业级Web应用对用户体验的要求要低一些。不过客户对“用户体验”的要求是“与日俱增”的,很多被“惯坏了”的用户已经不能忍受Postback带来的页面刷新,所以Ajax在企业级Web应用中得到了广泛的应用。企业级Web应用的一个特点是以“数据处理”为主,所以“面向绑定”的Knockout.js 是一个不错的选择。ASP.NET Web API,作为.NET平台最好的REST服务开发平台(主要与WCF相比),则可以以服务的形式提供对数据的后台处理。

一、一个简单的基于CRUD的Web应用

在《通过ASP.NET Web API + JQuery创建一个简单的Web应用》中,我采用jQuery + ASP.NET Web API构建了一个单纯的对单一数据进行CRUD操作的应用,对于数据在界面上的呈现,我是通过jQuery 动态生成HTML的方式实现的。现在我们通过Knockout.js来进行数据绑定,你会发现我们代码会变得很优雅。

这个简单的Demo应用用于模拟“联系人管理”。当页面加载的时候,所有的联系人列表被列出来。在同一个页面中,我们可以添加一个新的联系人,也可以修改和删除现有联系人信息。整个应用唯一的页面在浏览器中的呈现效果如下图所示。

image

二、通过ASP.NET Web API提供服务

先来看看ApiController的定义。如下面的代码片断所示,我们定义了一个名为ContactsController的ApiController用于完成针对联系人的CRUD操作,我们采用HTTP Method(Get、Post、Put和Delete)对Action方法进行命名,因为在进行Action匹配的时候会默认以Http Method作为前缀进行匹配。

   1: public class ContactsController : ApiController

   2: {

   3:     private static List<Contact> contacts = new List<Contact>

   4:     {

   5:         new Contact{ Id = "001", FirstName = "San", LastName="Zhang", PhoneNo="123", EmailAddress="zhangsan@gmail.com"},

   6:         new Contact{ Id = "002", FirstName = "Si", LastName="Li", PhoneNo="456", EmailAddress="lisi@gmail.com"}

   7:     };

   8:  

   9:     public IEnumerable<Contact> Get()

  10:     {

  11:         return contacts;

  12:     }

  13:  

  14:     public Contact Get(string id)

  15:     {

  16:         return contacts.FirstOrDefault(c => c.Id == id);

  17:     }

  18:  

  19:     public void Put(Contact contact)

  20:     {

  21:         contact.Id = Guid.NewGuid().ToString();

  22:         contacts.Add(contact);

  23:     }

  24:  

  25:     public void Post(Contact contact)

  26:     {

  27:         Delete(contact.Id);

  28:         contacts.Add(contact);

  29:     }

  30:  

  31:     public void Delete(string id)

  32:     {

  33:         Contact contact = contacts.FirstOrDefault(c => c.Id == id);

  34:         contacts.Remove(contact);

  35:     }

  36: }

  37:  

  38: public class Contact

  39: {

  40:     public string Id { get; set; }

  41:     public string FirstName { get; set; }

  42:     public string LastName { get; set; }

  43:     public string PhoneNo { get; set; }

  44:     public string EmailAddress { get; set; }

  45: }

和ASP.NET MVC Web应用一样,我们同样采用URL路由机制来实现请求地址与目标Controller和Action的映射,而针对API默认注册的路有如下所示(这里调用的方法是MapHttpRoute而不是MapRoute)。

   1: public class RouteConfig

   2: {

   3:     public static void RegisterRoutes(RouteCollection routes)

   4:     {

   5:         routes.MapHttpRoute(

   6:             name: "DefaultApi",

   7:             routeTemplate: "api/{controller}/{id}",

   8:             defaults: new { id = RouteParameter.Optional }

   9:         );

  10:     }

  11: }

按照注册的路由规则和Action方法名称与HTTP方法的默认影射机制,我们可以直接在浏览器中分别访问地址“/api/contacts”和“/api/contacts/001”得到所有联系人列表和ID为“001”的联系人信息。得到的结果如下图所示。

image

三、通过jQuery进行Ajax调用,利用Knockout.js进行数据绑定

我们通过ASP.NET MVC来构建Web应用,默认的HomeController定义如下,默认的Index操作仅仅是将默认的View呈现出来而已。

   1: public class HomeController : Controller

   2: {

   3:     public ActionResult Index()

   4:     {

   5:         return View();

   6:     }

   7: }

下面是整个View的定义。我们采用jQuery进行Ajax调用ApiController进行联系人的获取、添加、修改和删除,数据和命令(添加、修改和删除)的绑定是通过Knockout.js来完成的。

   1: <!DOCTYPE html>

   2: <html lang="en">

   3:     <head>

   4:         <title>@ViewBag.Title - My ASP.NET MVC Application</title>

   5:         @Styles.Render("~/Content/css" )

   6:         <script type="text/javascript" src="../../Scripts/jquery-1.6.2.min.js"></script>
   1:  

   2:         <script type="text/javascript" src="../../Scripts/knockout-2.0.0.js">

   1: </script>       

   2:     </head>

   3:     <body>

   4:     <div id="contacts">

   5:          <table>

   6:             <tr>

   7:                 <th>First Name</th>

   8:                 <th>Last Name</th>

   9:                 <th>Phone No.</th>

  10:                 <th>Email Address</th>

  11:                 <th></th>

  12:             </tr>

  13:             <tbody>

  14:                 <!-- ko foreach: contacts -->

  15:                 <tr>

  16:                     <td data-bind="text: FirstName" />

  17:                     <td data-bind="text: LastName" />

  18:                     <td data-bind="text: PhoneNo" />

  19:                     <td><input type="text" class="textbox long" data-bind="value: EmailAddress" /></td>

  20:                     <td>

  21:                         <a href="#" data-bind="click: $root.updateContact">Update</a><a href="#" data-bind="click: $root.deleteContact">Delete</a>

  22:                     </td>

  23:                 </tr>

  24:                 <!-- /ko -->

  25:                 <tr data-bind="with: addedContact">

  26:                     <td><input type="text" class="textbox" data-bind="value: FirstName"</td>

  27:                     <td><input type="text" class="textbox" data-bind="value: LastName"</td>

  28:                     <td><input type="text" class="textbox" data-bind="value: PhoneNo"</td>

  29:                     <td><input type="text" class="textbox long" data-bind="value: EmailAddress"</td>

  30:                     <td><a href="#" data-bind="click: $root.addContact">Add</a></td>

  31:                 </tr>

  32:             </tbody>

  33:         </table>

  34:     </div>

  35:     <script type="text/javascript" >

  36:         function contactManagerModel() {

  37:             self = this;

  38:             self.contacts = ko.observableArray();

  39:             self.addedContact = ko.observable();

抱歉!评论已关闭.