REFERENCE FROM : http://www.cnblogs.com/artech/archive/2012/07/04/Knockout-web-api.html

较之面向最终消费者的网站,企业级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应用用于模拟“联系人管理”。当页面加载的时候,所有的联系人列表被列出来。在同一个页面中,我们可以添加一个新的联系人,也可以修改和删除现有联系人信息。整个应用唯一的页面在浏览器中的呈现效果如下图所示。

二、通过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”的联系人信息。得到的结果如下图所示。

三、通过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();
  40:  
  41:             self.loadContacts = function () {
  42:                 $.get("/api/contacts", null, function (data) {
  43:                     self.contacts(data);
  44:                     var emptyContact = { Id: "-1", FirstName: "", LastName: "", PhoneNo: "", EmailAddress: "" };
  45:                     self.addedContact(emptyContact);
  46:                     $("table tr:odd").addClass("oddRow");
  47:                 });
  48:             };
  49:  
  50:             self.addContact = function (data) {
  51:                 if (!self.validate(data)) {
  52:                     return;
  53:                 }
  54:                 $.ajax({
  55:                     url: "api/contacts/",
  56:                     data: self.addedContact(),
  57:                     type: "PUT",
  58:                     success: self.loadContacts
  59:                 });
  60:             };
  61:  
  62:             self.updateContact = function (data) {
  63:                 $.ajax({
  64:                     url: "api/contacts/" + data.Id,
  65:                     data: data,
  66:                     type: "POST",
  67:                     success: self.loadContacts
  68:                 });                        
  69:             };
  70:  
  71:             self.deleteContact = function (data) {
  72:                 $.ajax({
  73:                     url: "api/contacts/" + data.Id,
  74:                     type: "DELETE",
  75:                     success: self.loadContacts
  76:                 });
  77:             };
  78:  
  79:             self.validate = function (data) {
  80:                 if (data.FirstName && data.LastName && data.PhoneNo && data.EmailAddress) {
  81:                     return true;
  82:                 }
  83:                 alert("Please provide complete contact information!");
  84:                 return false;
  85:             }
  86:             self.loadContacts();
  87:         }
  88:         ko.applyBindings(new contactManagerModel());
  89:     
</script>
   7:     </body>
   8: </html>

通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用的更多相关文章

  1. ASP.NET Web Api构建基于REST风格的服务实战系列教程

    使用ASP.NET Web Api构建基于REST风格的服务实战系列教程[十]——使用CacheCow和ETag缓存资源 系列导航地址http://www.cnblogs.com/fzrain/p/3 ...

  2. ASP.NET WEB API构建基于REST风格

    使用ASP.NET WEB API构建基于REST风格的服务实战系列教程[开篇] 最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http ...

  3. HttpActionDescriptor,ASP.NET Web API又一个重要的描述对象

    HttpActionDescriptor,ASP.NET Web API又一个重要的描述对象 通过前面对“HttpController的激活”的介绍我们已经知道了ASP.NET Web API通过Ht ...

  4. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【开篇】【持续更新中。。。】

    最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http://bitoftech.net/2013/11/25/detailed-tuto ...

  5. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【九】——API变了,客户端怎么办?

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 一旦我们将API发布之后,消费者就会开始使用并和其他的一些数据混在一起.然而,当新的需求出现 ...

  6. asp.net web api 构建api帮助文档

    1 概要 创建ASP.NET Web Api 时模板自带Help Pages框架. 2 问题 1)使用VS创建Web Api项目时,模板将Help Pages框架自动集成到其中,使得Web Api项目 ...

  7. 使用ASP.NET WEB API构建基于REST风格的服务实战系列教程(一)——使用EF6构建数据库及模型

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 使用Entity Framework Code First模式构建数据库对象 已经决定使用EF C ...

  8. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【二】——使用Repository模式构建数据库访问层

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在数据访问层应用Repository模式来隔离对领域对象的细节操作是很有意义的.它位于映射层 ...

  9. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【三】——Web Api入门

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 经过前2节的介绍,我们已经把数据访问层搭建好了,从本章开始就是Web Api部分了.在正式开 ...

随机推荐

  1. SQL Queries from Transactional Plugin Pipeline

    Sometimes the LINQ, Query Expressions or Fetch just doesn't give you the ability to quickly query yo ...

  2. ArcGIS JS 学习笔记3 实现百度风格的BubblePopup

    1. 开篇 模仿是最好的学习,这次我们继续山寨百度,通过自定义Infowindow来实现百度风格的BubblePopup 2.准备 2.1 Copy模板 先打开百度地图,按下f12吧BubblePop ...

  3. 【Android】实现XML解析的几种技术

    本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...

  4. 如何设置TextView控件的背景透明度和字体透明度

    如何设置TextView控件的背景透明度和字体透明度 设计师给的标注都是类似这样的: 字号:26 颜色:#000000 透明度:80% 其实,程序上只要需要一个色值就OK了,那么这个色值我如何计算呢? ...

  5. [Oracle]快速插入大量(100w)数据

    背景:无论在开发调试或者软件测试中,测试数据的准备是调试/测试执行前重要和必要的一个环节,因此以下几种方式可以快速插入大量数据: 第一种方法: declare   -- Local variables ...

  6. Cloudera5.8.3 HBase1.2.0开发必须的jar包

    Cloudera的HBase开发环境下载依赖包特别麻烦,通常是直接在CDH服务器上拷.

  7. 不同版本SQL SERVER备份还原时造成索引被禁用

    以下测试例子以SQL 2008备份,在SQL2014还原,造成索引被禁用. --备份环境(SQL Server 2008 R2) /* MicrosoftSQL Server 2008 R2 (RTM ...

  8. windows系统快捷操作の高级篇

    上次介绍了windows系统上几个比较好用的软件和系统快捷键,虽然有些很方便,但是毕竟还是太少了,而且无法自定义专属于自己的快捷键.所以我写了这么一篇教程,主要介绍两个神器:windows平台上的au ...

  9. 【转】java NIO 相关知识

    原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...

  10. MySQL优化实例

    这周就要从泰笛离职了,在公司内部的wiki上,根据公司实际的项目,写了一些mysql的优化方法,供小组里的小伙伴参考下,没想到大家的热情很高,还专门搞了个ppt讲解了一下. 举了三个大家很容易犯错的地 ...