初试ASP.NET Web API/MVC API(附Demo)

写在前面

  ASP.NET Web API是​​一个框架,能够很容易构建达成了普遍的HTTP服务客户端,包括浏览器和移动设备。是构建RESTful应用程序的理想平台的.NET框架。html

  上面是微软对Web API给出的定义,其中包含两个关键字:HTTP和RESTful,其实从这一方面,你们就能够看出Web API和它的同胞兄弟:WebService和WCF有些不一样了。node

HTTP

  对于HTTP你们都不是很陌生,由于咱们天天浏览网页填写的URL就是HTTP开头,但只是知道有这个东西,确没有想过它是什么,就好像咱们对世间万物有着模糊的认识,但认识东西的确不多。web

  也能够从另外一方面去理解,曾经看一个电视节目,有个嘉宾在录制的过程当中,忽然抬起头对着天花板仰望,而后主持人很惊讶问他在干嘛?他说:我在思考宇宙有没有尽头?主持人接着问:那宇宙有没有尽头?他淡然的回答道:有就有,没有就没有。固然观众和主持人都笑做一团,你会笑吗?透过现象看本质,其实这个思想和老庄的思想很合拍,扯远了。编程

HTTP即超文本传送协议。json

超文本传输协议 (HTTP-Hypertext transfer protocol) 是一种详细规定了浏览器和万维网服务器之间互相通讯的规则,经过因特网传送万维网文档的数据传送协议。api

  从定义中看出HTTP是一种协议,超文本传输协议,那什么是超文本?和咱们所说的富文本有些区别,超文本也是一种文本格式,那能够把它当作是文本与文本之间关联而组成的网状文本,有点相似于面向对象中对象的集合,虽然是对象的集合,但自己也是一个对象。跨域

  HTTP协议有下面三个基本特色:浏览器

  • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法经常使用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不一样。因为HTTP协议简单,使得HTTP服务器的程序规模小,于是通讯速度很快。
  • 灵活:HTTP容许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  • 无状态:无状态是指协议对于事务处理没有记忆能力。缺乏状态意味着若是后续处理须要前面的信息,则它必须重传,这样可能致使每次链接传送的数据量增大。

  相对于Web API来讲,HTTP不仅是为了生成Web页面,它也是一个强大的平台建设公开服务和数据的API。HTTP是简单、 灵活和无处不在,所以几乎任何平台均可以有一个HTTP库,所以,HTTP服务能够到达范围普遍的客户端,包括浏览器、移动设备和传统的桌面应用程序。服务器

RESTful

  RESTful架构概念是Fielding提出的,Fielding这号人物就是上面HTTP协议的主要设计者之一。咱们先看下RESTful这个词,ful是跟在名词以后,表示程度,什么什么的,例如helpful乐于助人的,所以咱们能够看出符合REST的架构就能够称为RESTful,接着咱们看下REST,全称为“Representational State Transfer”,意为“表现层状态转化”网络

在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,获得一个功能强、性能好、适宜通讯的架构。  -Fielding

  这是Fielding在论文中所提到的,对于REST虽然说是架构,但若是深刻一点,就像是HTTP协议同样,能够当作一种规则或是协议。咱们从一个地点到另外一个地点,能够坐汽车、高铁、飞机等,对于REST就像是其中的一种交通方式,但REST的根本是HTTP协议,也就是说REST是基于HTTP协议的,这点就像坐汽车必需要有公路,坐高铁必需要有铁路是同样的道理,有时候为何选用REST,就像咱们从南京到徐州,选择坐高铁而不选择坐飞机同样。

  上面这个比喻可能不太恰当,可是思想都是相同的,若是有可能的话能够看下一些哲学方面的书,像庄子的道德经,毕竟编程是哲学或是艺术的另外一类体现,又扯远了。

  “Representational State Transfer”咱们分解下:

  • Representational 表现层:表现层表现什么,应该呈现资源(Resources),一个图片、一段文字、一个文件都成为资源,每一个资源都用一个URI(统一资源定位符)指向它,表现层就是调用URI把资源呈现出来,并且只是呈现,不作其余操做。举个例子:有些网址最后的".html"后缀名是没必要要的,由于这个后缀名表示格式,属于"表现层"范畴,而URI应该只表明"资源"的位置。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对"表现层"的描述。
  • State Transfer 状态转化:访问一个网站,就表示客户端和服务器发生一次交互行为,在这个过程当中,就不发生数据和状态的转化,上面说到HTTP协议具备无状态性,若是客户端操做服务器,必需要状态转化,这个体如今表现层上,因此叫“表现层状态转化”

  经过上面的理解,能够总结下什么是RESTful架构:

  1. 每个URI表明一种资源。
  2. 客户端和服务器之间,传递这种资源的某种表现层。
  3. 客户端经过四个HTTP动词(PUT、GET、POST和DELETE),对服务器端资源进行操做,实现"表现层状态转化"。

建立Web API

  关于Web API的实现方式,.net提供了一套机制就是ASP.NET MVC API,相似MVC的方式,实现起来很简单,也不须要你去关注HTTP和RESTful的一些东西,当你去新建项目的时候,一切东西.net都帮你搞定了,是好仍是很差?只能呵呵笑过。

  下面咱们就一步一步的建立一个ASP.NET MVC API

  1,新建ASP.NET MVC WebMvcApiDemo程序,选择Web API模板类型。

  2,建立News模型,虽然建立的是MVC项目,可是咱们通常只用到控制器和模型。

 1     public class News
 2     {
 3         /// <summary>
 4         /// 新闻ID
 5         /// </summary>
 6         public int Id { get; set; }
 7         /// <summary>
 8         /// 新闻标题
 9         /// </summary>
10         public string Title { get; set; }
11         /// <summary>
12         /// 新闻内容
13         /// </summary>
14         public string Content { get; set; }
15         /// <summary>
16         /// 新闻做者
17         /// </summary>
18         public string Author { get; set; }
19         /// <summary>
20         /// 发布新闻时间
21         /// </summary>
22         public DateTime CreateTime { get; set; }
23     }

  3,建立数据模拟类NewsRepository,用于查询数据。

 1     public class NewsRepository
 2     {
 3         public IEnumerable<News> GetAllNews()
 4         {
 5             News[] news = new News[] 
 6             { 
 7                 new News { Id = 1, Title="新闻标题1", Content="新闻内容1", Author="xishuai", CreateTime=DateTime.Now }, 
 8                 new News { Id = 2, Title="新闻标题2", Content="新闻内容2", Author="xishuai", CreateTime=DateTime.Now }, 
 9                 new News { Id = 3, Title="新闻标题2", Content="新闻内容3", Author="xishuai", CreateTime=DateTime.Now }
10             };
11             return news;
12         }
13     }

  4,建立NewsController控制器,注意的是:新建控制器的时候,模板选择“空 API 控制器”,与MVC控制器不一样的是,API控制器继承ApiController基类。在咱们新建ApiDemo的MVC项目的时候,自动生成了一个ValuesController API控制器,打开后咱们发现,有不少自动生成的方法,请求方式就是咱们上面说GET、POST、PUT和DELETE的四种HTTP请求方式,咱们这边作一个Get的,获取所有新闻或是指定新闻ID获取,返回结果格式为XML。

 1     public class NewsController : ApiController
 2     {
 3         /// <summary>
 4         /// GET获取所有新闻
 5         /// </summary>
 6         /// <returns></returns>
 7         [HttpGet]
 8         public HttpResponseMessage GetAllNews()
 9         {
10             var news = new NewsRepository().GetAllNews();
11             return new HttpResponseMessage()
12             {
13                 RequestMessage = Request,
14                 Content = new XmlContent(SimpleXmlConverter.ToXmlDocument<News>(news, "NewsRoot"))
15             };
16         }
17 
18         /// <summary>
19         /// GET获取指定ID新闻
20         /// </summary>
21         /// <param name="ID"></param>
22         /// <returns></returns>
23         [HttpGet]
24         public HttpResponseMessage GetNewsByID(int ID)
25         {
26             var news = new NewsRepository().GetAllNews().Where((p) => p.Id == ID);
27             return new HttpResponseMessage()
28             {
29                 RequestMessage = Request,
30                 Content = new XmlContent(SimpleXmlConverter.ToXmlDocument<News>(news, "NewsRoot"))
31             };
32         }
33     }

  这里面主要用到两个转化类:XmlContent和SimpleXmlConverter,有关这两个类的详细代码能够下载Demo看下。

  5,路由配置Web API和MVC的路由配置很类似,主要区别是Web API使用HTTP方法而不是URI路径来选择动做,路由文件WebApiConfig,以下:

1             config.Routes.MapHttpRoute(
2                 name: "DefaultApi",
3                 routeTemplate: "api/{controller}/{action}/{id}",
4                 defaults: new { id = RouteParameter.Optional }
5             );

  其实写到这里建立Web API的代码就差很少了,固然复杂的操做能够扩充,用.net开发就是这么简单,只要完成业务逻辑就好了,呵呵。

调用Web API

  调用Web API有不少种方式,js能够调用,就像咱们写MVC请求数据同样,这种是同一域下调用,Web API也是这种方式就没什么意思了,若是使用js调用就必须跨域操做,这边咱们使用HttpClient的方式。

  1,新建控制台应用程序-ClientDemo。

  2,安装Web API 客户端库,工具-程序包管理器-程序包管理控制平台,输入命令:Install-Package Microsoft.AspNet.WebApi.Client

  上面新建的ClientDemo项目.net framework版本是4.0,安装HttpClient的时候报下面错误:

  .net framework版本改成4.5就安装成功了,难道HttpClient只支持4.5以上?查了下MSDN,HttpClient确实只支持.net framework4.5,难道之前程序若是使用HttpClient要把.net framework改为4.5?有点郁闷。

  4,建立HttpClient,先贴下代码:

 1         static void Main(string[] args)
 2         {
 3             RunAsync().Wait();
 4         }
 5 
 6         static async Task RunAsync()
 7         {
 8             using (var client = new HttpClient())
 9             {
10                 client.BaseAddress = new Uri("http://localhost:8077/");
11                 client.DefaultRequestHeaders.Accept.Clear();
12                 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
13 
14                 string xmlString = await client.GetStringAsync("api/News/GetAllNews");
15                 XmlDocument xmlDoc = new XmlDocument();
16                 xmlDoc.LoadXml(xmlString);
17                 XmlNodeList nodeList = xmlDoc.GetElementsByTagName("News");
18                 foreach (XmlNode node in nodeList)
19                 {
20                     Console.WriteLine("新闻ID:" + node.SelectSingleNode("Id").InnerText);
21                     Console.WriteLine("新闻标题:" + node.SelectSingleNode("Title").InnerText);
22                     Console.WriteLine("新闻内容:" + node.SelectSingleNode("Content").InnerText);
23                     Console.WriteLine("做者:" + node.SelectSingleNode("Author").InnerText);
24                     Console.WriteLine("新闻发布时间:" + node.SelectSingleNode("CreateTime").InnerText);
25                     Console.WriteLine("======================");
26                 }
27                 Console.ReadKey();
28             }
29         }

  Main 函数调用一个名为RunAsync的异步方法,而后会阻止,直到RunAsync完成。许多的HttpClient方法是异步,由于他们执行网络 i/o 操做。MediaTypeWithQualityHeaderValue是定义传输格式,若是使用json则为“application/json”,这边要与Web API格式一致,XML获取使用的是GetStringAsync方法,而后转换为XmlDocument,网上找了一种GetStreamAsync方法获取,经过Stream转化为字符串,可是转化后的字符串为空。

  上面调用Web API的是获取所有新闻,若是调用经过新闻ID获取新闻,GetStringAsync的方法参数只须要改成“api/News/GetNewsByID/新闻ID”就能够了。

  5,关于Web API的发布问题,这个问题花了很多时间,一个一个问题出现及解决,首先咱们先不急着调用,先发布浏览,若是浏览器浏览没问题的话再调用。Web API的发布和MVC差很少,须要注意下面几点:

  • 文件权限别忘了配置,要配置every one。
  • 应用程序池选择“ASP.NET v4.0 DefaultAppPool”。
  • 选择应用程序池以后要配置“ISAPI 和 CGI 限制”的4.0版本设置为容许,要否则出现“因为 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,没法提供您请求的页面。”的错误。
  • “Newtonsoft.Json”文件引用。
  • “An error has occurred.Multiple actions were found that match the request”,这个错误信息是Web API的路由没有配置好,要检查下。
  • “Response status code does not indicate success: 404 (Not Found)”,这个错误信息也是路由问题。
  • “Response status code does not indicate success: 500 (Internal Server Error).”,这个是服务器问题,也就是Web API的代码问题。

运行截图及Demo下载

  Web API浏览器请求截图:

  Web API发布运行截图:

  客户端调用运行截图:

  Demo下载地址:http://pan.baidu.com/s/1gdopRub

  HTTP请求的四种方法(PUT、GET、POST和DELETE)本篇只是讲到GET,HTTP的数据传输格式(json、xml等)也只是说了XML,但都是大同小异,触类旁通可得。

  若是你以为本篇文章对你有所帮助,请点击右下部“推荐”,^_^

相关文章
相关标签/搜索