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

时间:2023-01-11 16:34:45

系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html

前言

经过前2节的介绍,我们已经把数据访问层搭建好了,从本章开始就是Web Api部分了。在正式开始之前,再一次回顾一下Web Api的应用场景:Web Api可以与 MVC,WebForm结合使用,也可以作为一个单独的Web服务。在正式讨论Web Api的配置以及如何构造我们的URI来消费资源之前,我们必须理解Http方法与我们将要访问的资源之间的关系。举个简单的例子,我们把模型”Course”作为我们访问的资源,下面就列举了访问这个资源的http方法:

Action HTTP Verb Relative URI
获取所有课程信息 GET /api/courses
根据某个Id获取单个课程 GET /api/courses/id
新增一个课程 POST /api/coursesNew course is sent in POST body
更新一个课程 PUT or PATCH /api/courses/idUpdated course is sent in POST body
删除一个课程 DELETE /api/courses/id

第一步:创建Web Api项目

右击解决方案->添加新建项目

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

下一步:

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

点击确定

第二步:配置第一个路由

在创建好项目之后,我们可以在App_Start文件夹下看到“WebApiConfig”类。这个类就是用来配置路由信息的,这个类最终会在“Global.asax”的Application_Start()方法中被调用,后面我们会在这个这个类里面配置多条路由信息。

配置第一个路由:

config.Routes.MapHttpRoute(
name: "Courses",
routeTemplate: "api/courses/{id}",
defaults: new {controller="courses", id = RouteParameter.Optional }
);

分析一下上面这段代码:我们创建了一个Courses的路由规则,这个路由模板会匹配到“api/courses/{id}”的URI,在这个模板定义了2个默认值(api,courses)以及一个可选值(id)。对于“/api/courses or /api/courses/5”URI就会被我们的路由模板匹配到,同时“/api/courses”URI也会被匹配到,因为Id是可选的。

第三步:添加第一个控制器(courses controller)

Web Api中的Controller是用来处理客户端Http请求的(与MVC中的Controller类似),首先,创建Controller——右击Controller文件夹->新建项->控制器

然后出现下面窗口:

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

选择Web API 2控制器-空,并命名为CoursesController。然后确定

打开刚才创建的Controller,可以看到我们创建的类继承自“ApiController”。同时对于这个类的类名必须是“CoursesController”,因为在Web Api中默认的控制器选择方式是寻找所有继承自“ApiController”类并且这个类是以“Courses”开头(这是在我们的路由规则中配置的)的控制器。

第四步:在Controller中添加Action

首先,我们创建上述表格列举到的前2个方法(GetAllCourses,GetCourseById)

方法的选择是智能的,如果我们创建了2个方法Get()和GetCourse(int id),假设我们发送一个GET请求并且URI是“/api/courses/5”,那么“GetCourse(int id)”方法就会被选择执行,这是因为方法是以Get开头而且URI中包含Id的值。这种选择方式同样适用以其他的Http方法(put,delete,post),下面上代码:

public class CoursesController : ApiController
{
public List<Course> Get()
{
ILearningRepository repository = new LearningRepository(new LearningContext()); return repository.GetAllCourses().ToList();
} public Course GetCourse(int id)
{
ILearningRepository repository = new LearningRepository(new LearningContext()); return repository.GetCourse(id);
}
}

当我们创建一个Get请求并且URI是“http://localhost:{your_port}/api/courses”时候,Get()方法会被选择调用,下面是相应的部分代码:

[
{
"Id": 1,
"Name": "History Teaching Methods 1",
"Duration": 3,
"Description": "The course will talk in depth about: History Teaching Methods 1",
"CourseTutor": {
"Courses": [],
"Id": 1,
"Email": "Ahmad.Joudeh@outlook.com",
"UserName": "AhmadJoudeh",
"Password": "SWDQNPSE",
"FirstName": "Ahmad",
"LastName": "Joudeh",
"Gender": 0
},
"CourseSubject": {
"Courses": [],
"Id": 1,
"Name": "History"
},
"Enrollments": []
},
{
"Id": 2,
"Name": "History Teaching Methods 2",
"Duration": 3,
"Description": "The course will talk in depth about: History Teaching Methods 2",
"CourseTutor": {
"Courses": [],
"Id": 1,
"Email": "Ahmad.Joudeh@outlook.com",
"UserName": "AhmadJoudeh",
"Password": "SWDQNPSE",
"FirstName": "Ahmad",
"LastName": "Joudeh",
"Gender": 0
},
"CourseSubject": {
"Courses": [],
"Id": 1,
"Name": "History"
},
"Enrollments": []
},

如果你发送一个Get请求并且URI是“http://localhost:{your_port}/api/courses/5”。那么GetCourse(int id)将会被选择调用执行。但是很遗憾在调用这个方法之后就会产生一个异常,这个异常信息简单来说就是“序列化对象的时候出现了循环依赖”,换句话说就是对象间循环引用(Course>Enrollment>Course>Enrollment>etc…)

总结

到目前为止我们已经让Web Api跑起来了,但仍然有很多不足之处:

返回对象时出现循环依赖,可以通过模型工厂模式解决。

我们返回了领域模型中所有的字段给客户端,然而有一些敏感信息不应该返回(例如:password字段),解决方案:模型工厂模式

每一个返回给客户端的资源都应该包含一个URI以便客户端查询,解决方案依旧是模型工厂模式。

对于返回单个资源,我们应当返回相应的状态码(例如:成功200,资源未找到404等),解决方案:HttpResponseMessage对象

在每个方法里我们都实例化了一个repository,这个对象包含了一些昂贵的操作(例如:数据库连接),解决方案:依赖注入模式

对于返回的Json对象格式是以“帕斯卡”风格的(例如“FirstName”),然而我们的Api有很大的可能被带有Javascript的客户端消费,对于JS开发者来说可能更适合“驼峰”风格(例如”firstName”)的数据。解决方案:配置Json格式。

ok,下一章我们就着重解决上述的问题

本章代码:http://yun.baidu.com/share/link?shareid=2010367762&uk=17559114&third=0

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

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

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

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

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

  3. 使用ASP&period;NET Web Api构建基于REST风格的服务实战系列教程【八】——Web Api的安全性

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 这一篇文章我们主要来探讨一下Web Api的安全性,到目前为止所有的请求都是走的Http协议 ...

  4. &lbrack;转&rsqb;使用ASP&period;NET Web Api构建基于REST风格的服务实战系列教程【八】——Web Api的安全性

    本文转自:http://www.cnblogs.com/fzrain/p/3552423.html 系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html ...

  5. 使用ASP&period;NET Web Api构建基于REST风格的服务实战系列教程【四】——实现模型工厂,依赖注入以及格式配置

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在上一篇中,我们已经初步开始使用Web Api了,但同时出现了一些很多不足之处,本章我们就着 ...

  6. 使用ASP&period;NET WEB API构建基于REST风格的服务实战系列教程&lpar;一&rpar;——使用EF6构建数据库及模型

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

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

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

  8. 使用ASP&period;NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法&lpar;Put&comma;Post&comma;Delete&rpar;

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新 ...

  9. 使用ASP&period;NET Web Api构建基于REST风格的服务实战系列教程【六】——实现资源间的关联

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 这一篇文章主要介绍一下资源间的关联——例如在学生和课程之间就存在这样的关联:每一个课程都会有 ...

随机推荐

  1. webuploader在IE8&sol;9下上传遇到的两个问题

    最近在做图片上传功能. 点击一个按钮,弹出一个iframe,它是百度的webuploader插件 在点击关闭按钮时,IE9下总是会报错: __flash__removeCallback未定义错误 解决 ...

  2. OpenCV2&colon;Mat属性type,depth,step

    在OpenCV2中Mat类无疑使占据着核心地位的,前段时间初学OpenCV2时对Mat类有了个初步的了解,见OpenCV2:Mat初学.这几天试着用OpenCV2实现了图像缩小的两种算法:基于等间隔采 ...

  3. MAC 远程桌面链接 证书或链接无效

    RDC --> 首选项  -->  安全性 --> 勾选即使验证失败也要链接.   问题解决.

  4. C&num;委托的介绍&lpar;delegate、Action、Func、predicate&rpar;【转】

    转自 http://www.cnblogs.com/akwwl/p/3232679.html 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1 ...

  5. HDU-4705 Y 树形DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4705 题意:给一颗树,从树上任意选择3个点{A,B,C},要求他们不在一条链上,求总共的数目. 容易想 ...

  6. POJ 3311 Hie with the Pie (BFS&plus;最短路&plus;状态压缩)

    题意:类似于TSP问题,只是每个点可以走多次,求回到起点的最短距离(起点为点0). 分析:状态压缩,先预处理各点之间的最短路,然后sum[i][buff]表示在i点,状态为buff时所耗时...... ...

  7. EF&plus;SQLSERVER控制并发下抢红包减余额(改进)

    最近几年想必大家一听到哪里有抢红包可以抢,马上会拿起手机点去~~~~然后问题来了... 如何控制在同一时间保证数据库中扣减红包余额不会出错.之前我们的做法是直接锁程序,这样子带来的坏处就是等待时间太长 ...

  8. &period;net异步性能测试(包括ASP&period;NET MVC WebAPI异步方法)

    很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语 ...

  9. 【Python】Talk Python To Me Podcast播客

    这是Python相关的一个播客,通过播客的形式给大家讲述python那点事,相关的链接都会列出来,有一些是由文本内容的,如果听不太懂就看看英文原文.不*的情况下,网页打开没有问题,但是播 ...

  10. windows每天备份文件的bat脚本【原创】

    备份昨天文件的脚本 @echo off set yy=%DATE:~,% set mm=%DATE:~,% set ,% ::前一天的日期,格式化输出 ,date)>vbs.vbs for /f ...