Contact Manager Web API 示例[1]CRUD 操作

联系人管理器web API是一个Asp.net web api示例程序,演示了通过ASP.NET Web API 公开联系信息,并允许您添加和删除联系人,示例地址http://code.msdn.microsoft.com/Contact-Manager-Web-API-0e8e373d . 下面的文章以这个示例讲解ASP.NET Web API的各方面知识:

1、CRUD操作: CURD 是 "Create, Read, Update, Delete" (新增、读取、更新、删除) 的简写,这四个动作是数据库基本操作。

Web API CRUD 方法说明

Action说明

HTTP方法

URI关连

取得所有联系人清单

GET

/api/contacts

透过 id 取得联系人数据

GET

/api/contacts/id

新增一位联系人

POST

/api/contacts

更新联系人数据

PUT

/api/contacts/id

删除联系人数据

DELETE

/api/contacts/id

由上表中,我们可以很清楚看到,有两种资源类型( resource types):

URI 资源类型

URI

说明

/api/contacts

列出所有联系人

/api/contacts/id

一位联系人

HTTP 方法

HTTP 主要方法 (GET, PUT, POST, DELETE) 能对应到 CURD 操作:

· GET 接收及显示。GET 在服务器应该没有副作用。

· PUT 更新。PUT 也能拿来"新增"使用,如果服务器允许 Client 去指定新的 URI。那范例的联系人管理将不允许使用 PUT 来新增。

· POST 新增。服务器会给 URI 分配新对象,然后返回此 URI 作为响应消息的一部分。

· DELETE 删除

新增资源

在 ASP.NET Web API,你能在 Model 使用强型别 CLR 对象,他们将会自动序列化为 XML 或 JSON 给 Client。在Model 目录Contact 类

public class Contact 
    { 
        public int ContactId { get; set; } 
        public string Name { get; set; } 
        public string Address { get; set; } 
        public string City { get; set; } 
        public string State { get; set; } 
        public string Zip { get; set; } 
        public string Email { get; set; } 
        public string Twitter { get; set; } 
        public string Self 
        { 
            get { return string.Format(CultureInfo.CurrentCulture, "contact/{0}", this.ContactId); } 
            set { } 
        } 
    }

使用仓储模式( Repository Pattern)

我们的 HTTP Service 需要储存联系人列表,此范例,联系人列表会储存在内存( List(Of T ) )。使用 Repository Pattern 会让此对象从我们的 Service 实作中切割出来。在 Model 目录,新增一个 Interface 接口,名称 IContactRepository.cs

public interface IContactRepository 
   { 
       void Update(Contact updatedContact); 
       Contact Get(int id); 
       List<Contact> GetAll(); 
       void Post(Contact contact); 
       void Delete(int id); 
   }

以上定义出我们需要的 CRUD 相关功能接口,然后一样在 Model 目录下新增一个新的类文件,类文件 "ContactRepository.cs",此类将实作 IContactRepository 接口。以下为相关实现:

    public class ContactRepository : IContactRepository 
    { 
        private int nextContactID; 
        private IList<Contact> contacts; 
        public ContactRepository() 
        { 
            contacts = new List<Contact>(); 
            contacts.Add(new Contact { ContactId = 1, Name = "Glenn Block", Address = "1 Microsoft Way", City = "Redmond", State = "Washington", Zip = "98112", Email = "gblock@microsoft.com", Twitter = "gblock" }); 
            contacts.Add(new Contact { ContactId = 2, Name = "Howard Dierking", Address = "1 Microsoft Way", City = "Redmond", State = "Washington", Zip = "98112", Email = "howard@microsoft.com", Twitter = "howard_dierking" }); 
            contacts.Add(new Contact { ContactId = 3, Name = "Yavor Georgiev", Address = "1 Microsoft Way", City = "Redmond", State = "Washington", Zip = "98112", Email = "yavorg@microsoft.com", Twitter = "digthepony" }); 
            contacts.Add(new Contact { ContactId = 4, Name = "Jeff Handley", Address = "1 Microsoft Way", City = "Redmond", State = "Washington", Zip = "98112", Email = "jeff.handley@microsoft.com", Twitter = "jeffhandley" }); 
            contacts.Add(new Contact { ContactId = 5, Name = "Deepesh Mohnani", Address = "1 Microsoft Way", City = "Redmond", State = "Washington", Zip = "98112", Email = "deepm@microsoft.com", Twitter = "deepeshm" }); 
            contacts.Add(new Contact { ContactId = 6, Name = "Brad Olenick", Address = "1 Microsoft Way", City = "Redmond", State = "Washington", Zip = "98112", Email = "brado@microsoft.com", Twitter="brado_23" }); 
            contacts.Add(new Contact { ContactId = 7, Name = "Ron Jacobs", Address = "1 Microsoft Way", City = "Redmond", State = "Washington", Zip = "98112", Email = "rojacobs@microsoft.com", Twitter = "ronljacobs" }); 
            nextContactID = contacts.Count + 1; 
        } 
        public void Update(Contact updatedContact) 
        { 
            var contact = this.Get(updatedContact.ContactId); 
            contact.Name = updatedContact.Name; 
            contact.Address = updatedContact.Address; 
            contact.City = updatedContact.City; 
            contact.State = updatedContact.State; 
            contact.Zip = updatedContact.Zip; 
            contact.Email = updatedContact.Email; 
            contact.Twitter = updatedContact.Twitter; 
        } 
        public Contact Get(int id) 
        { 
            return contacts.SingleOrDefault(c => c.ContactId == id); 
        } 
        public List<Contact> GetAll() 
        { 
            return contacts.ToList(); 
        } 
        public void Post(Contact contact) 
        { 
            contact.ContactId = nextContactID++; 
            contacts.Add(contact); 
        } 
        public void Delete(int id) 
        { 
            var contact = this.Get(id); 
            contacts.Remove(contact); 
        } 
    }

实现没有什么难处,要处理都是 List(Of Contact) 所提供的 .Add(), .Remove(), .Find() 以进行相关新增、删除、查询动作。另外,还利用 LINQ 的 .AsQueryable() 来将 List 型别转换,才有办法以 IQueryable() 来回传。以上利用 List 来仿真数据库,或者说,把 List 想象成内存里的数据库。

Web API Controller(ContactsController)

ContactsController是 HTTP Service 的程序代码,注意命名开始要对应到 HTTP Method,主要就是约定胜于配置理念。“约定”即规则。规则是预先定义的,工程师只需要按着规则来做事,就不需要额外的“配置”。当然也可以不对应,通过HttpMothod打标签也可以的。

取得资源

取得资源是 Read 与 GET 的对应关系。在联系人管理中提供了二个 Action,一个是读取所有联系人,一个是通过 id 来取得联系人。这两个 Action 都定义在 HTTP GET 方法,记得方法必须以 "Get..." 开头。

· GET /api/contacts

· GET /api/contacts/id

新增资源

新增资源是 Create 与 POST 的对应关系。要新增一位联系人,Client 送出一个 HTTP POST 请求,请求信息包含新联系人的相关内容。记得方法必须以 "Post..." 开头。

        public HttpResponseMessage<Contact> Post(Contact contact) 
        { 
            this.repository.Post(contact); 
            var response = new HttpResponseMessage<Contact>(contact) { StatusCode = HttpStatusCode.Created };
           string uri = Url.Route("default", new { id = contact.ContactId }); 
            response.Headers.Location = new Uri(Request.RequestUri, uri);
             return response; 
        }

默认从请求主体(request body)来而的参数解序列化后是复合(complex)类型。因此,我们预期 Client 传送给我们的是一个经序列化表现的联系人对象,使用 XML 或 JSON 来序列化。以上的实现考虑到两件事:

· Response code 默认,Web API Framework 设定回传状态代码(status code)为 200 (OK)。但按照 HTTP/1.1 协议,当一个 POST 请求会导致资源的建立,服务器应该响应的状态代码为 201 (Created)。

· Location当服务器新增一个资源,它应该在响应的 Location header 中包含新资源的 URI。

注意返回类型是 HttpResponseMessage(Of Contact)HttpResponseMessage(Of T) 型别是一个用强类型表示的 HTTP 响应消息。泛型参数 T 会取得 CLR 型别然后序列化到信息主体。

更新资源

更新资源是 Update 与 PUT 的对应关系。更新联系人作法相当直觉,记得方法必须以 "Put..." 开头。

public Contact Put(int id, Contact contact) 
{ 
           contact.ContactId = id; 
           this.repository.Update(contact); 
           return contact; 
}

方法中有二个参教,联系人 id 与 更新的联系人数据。id 参数会从 URI 路径取得,联系人参数是从请求主体解串行化而来。默认,ASP.NET Web API Framework 会从请求主体 (request body)里的 route 与 复合(complex) 型别来取得简易的参数类型。

删除资源

删除资源是 Delete 与 DELETE 的对应关系。

public HttpResponseMessage Delete(int id) 
{ 
            var deleted = this.repository.Get(id); 
            this.repository.Delete(id); 
            return new HttpResponseMessage(HttpStatusCode.NoContent); 
}

依据 HTTP 规范,DELETE 方法必须是 idmpotent(幂等),意味着几个相同 URI 的删除请求必须和一个删除请求有相同效果。因此,如果联系人已经被删除,方法应该不能回传错误码。 如果 DELETE 请求成功,你能回传状态 200 (OK) 描述该实体主体(即要删除的主体)的状态,或如果删除持续未处理回传状态 202 (Accepted) ,或没有实体主体回传状态 204 (No Content)。我们范例会返回状态 204 (No Content)。

CRUD 操作总结

在使用 ASP.NET Web API Framework 时,你能发现与 HTTP/1.1 规范有很大关连性,以前较很少关心与了解的内容,例如,PUT、DELETE、POST的处理,以及状态代码的处理等,现在变成要开注意的几个点。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

API代理,连接器和附加组件

我正在通过API服务提供商的一些100K的视图的研究,试图完善我对API下一步是什么?的看法。

27150
来自专栏葡萄城控件技术团队

MVC5:使用Ajax和HTML5实现文件上传功能

引言 在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能...

780100
来自专栏大数据风控

R中协同过滤算法

协同过滤(Collaborative Filtering,简称CF) 协同过滤常常被用于分辨某位特定顾客可能感兴趣的东西,这些结论来自于其他相似顾客对哪些产品感...

34450
来自专栏葡萄城控件技术团队

ASP.NET Web API 应用教程(一) ——数据流使用

相信已经有很多文章来介绍ASP.Net Web API 技术,本系列文章主要介绍如何使用数据流,HTTPS,以及可扩展的Web API 方面的技术,系列文章主要...

42780
来自专栏葡萄城控件技术团队

Google 新推出Background sync API

Background sync是Google新推出的Web API,可延迟用户行为,直到用户网络连接稳定。这样有助于保证用户想要发送的数据就是实际发送的数据。 ...

280100

云开发API连接器的最佳练习

Amazon Web Services,Microsoft Azure,Google Compute Engine等云服务提供商以及OpenStack,vClo...

31880
来自专栏Java技术分享

第十章:Shiro的Cache——深入浅出学Shiro细粒度权限开发框架

Shiro开发团队明白在许多应用程序中性能是至关重要的。Caching 是Shiro 中的一个重要功能,以确保安全操作保持尽可能的快。

20750
来自专栏葡萄城控件技术团队

.NET 新标准介绍

本文介绍如何使用 .NET 标准,更容易地实现向 .NET Core 迁移。文中会讨论计划包含的 APIs,跨构架兼容性如何工作以及这对 .NET Core 意...

21080
来自专栏大数据智能实战

tensorflow.models.rnn.rnn_cell.linear在tensorflow1.0版本之后找不到(附tensorflow1.0 API新变化)

由于版本更新关系,从原来的tensorflow低版本到升级到tensorflow1.0以上时,发现有很多API函数变化是很正常的事情,大多碰到的如: 如其中tf...

35070
来自专栏葡萄城控件技术团队

Winform文件下载之WebClient

最近升级了公司内部使用的一个下载小工具,主要提升了下面几点: 1. 在一些分公司的局域网中,连接不上外网 2. 服务器上的文件更新后,下载到的还是更新前的文件 ...

22150

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励