Mvc4中的WebApi的使用方式

一:简单介绍什么是Web api

REST属于一种设计风格,REST 中的 POST(新增数据),GET(取得数据),PUT(更新数据),DELETE(删除数据)来进行数据库的增删改查,而如果开发人员的应用程式符合REST原则,则它的服务为“REST风格Web服务“也称的RESRful Web API”。

微软的web api是在vs2012上的mvc4项目绑定发行的,它提出的web api是完全基于RESTful标准的,完全不同于之前的(同是SOAP协议的)wcf和webService,它是简单,代码可读性强的,上手快的,如果要拿它和web服务相比,我会说,它的接口更标准,更清晰,没有混乱的方法名称,有的只有几种标准的请求,如get,post,put,delete等,它们分别对应的几个操作,下面讲一下:

GET:生到数据列表(默认),或者得到一条实体数据

POST:添加服务端添加一条记录,记录实体为Form对象

PUT:添加或修改服务端的一条记录,记录实体的Form对象,记录主键以GET方式进行传输

DELETE:删除 服务端的一条记录

二:怎么定义的 Post Get Put 和 Delete

首先我们从MVC4 的WEB API模板自动创建的演示文件进行分析 
这里写图片描述

从演示的列子,我们可以看到在Action 中没有使用[HttpGet]、[HttpPost] 等修饰,那究竟它是如何运作的呢

Action 皆以HTTP 动词开头Get、Post、Put、Delete ,这个也是刚好符合 webapi的约定的,什么约定呢?

你调用什么类型的方法 ,例如 post 方法,那么他就去 你的所有的 action 里面 去找 以 post 开头的方法 ,名字可以随便叫,例如 postToDataBase 等等,只要开头匹配 就可以了

打个比喻,假设今天服务端收到了一个GET 请求时,会去查找对应的Controller 并且Action 以”Get…” 开头的方法,举个例子:GetMembers、GetTime,以此类推,如果我们从jQuery Ajax 发出了一个POST 请求,也会自动对应到以”Post…” 开头的Action 内,也就是说实际呼叫哪个Controller 的Action 不是利用网址来决定,而是依照HTTP 所送出的请求来决定,这也就是非常典型的REST风格,而在Web API 中也处理了回传的数据,让我们看看Get() 这个方法,回传IEnumerable 的方法,等于我们拥有了强类型。

我们再来看看默认的 api 路由表 
这里写图片描述

这里,只注册到了controller,没有到action,因为api的action名称是有约定的。

webapi大约有这样的约定:
action名称中有get的,0参数,匹配路由到/控制器
action名称中有get的,1参数,匹配路由到 /控制器/id
action名称中有post的,0参数,匹配路由到post方式的/控制器
action名称中有post的,1参数,匹配路由到post方式的/控制器/id



 对于返回,可以直接返回一个class,则apicontroller自动根据请求的content-type序列化成xml或者json。具体例子为,用ie打开相应api的url返回的是json,用chrome返回的就是xml。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

另外我们可以注意到在Post Put的方法参数有一个关键字[ FromBody ],而Get、Delete则没有。,事实上没有加[ FromBody ]就默认为[ FromUri ].

[ FromBody ]表示由请求文件本体中取得资料,就像一般表单Post Submit一样,取得资料的来源是由请求本体中取得,而[ FromUri ]则表示由URI中取得资料,就像在网址列中的所夹带的参数

在webapi的示范代码里,Get方法很简单只有一个id参数的传入并且是简单的int型,因此我们可以用 http://localhost/api/Values/1 这样的请求执行Get(int id)方法,但事实上并非每个请求都只用一个简单的参数就可以能搞定,有时我们可能需要2个或以上的参数才能传递或者是获取到数据,我们可以到路由里面改为接受两个参数,分别为{ p1 } & { p2 }

RouteTable.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "webapi/{controller}/{p1}/{p2}",
            defaults: new { id = System.Web.Http.RouteParameter.Optional }
        );
  • 1
  • 2
  • 3
  • 4
  • 5

那么对应的 Controller 里面获取Get的方法需要修改为

public string Get(String p1, String p2)
        {
            return p1 + "/" + p2;
        }
  • 1
  • 2
  • 3
  • 4

我们去调用一下试试 
这里写图片描述

这种方法,虽然比较简单,但是如果我们的参数更多的时候,还是这样去修改 路由也是很麻烦的,我们就采用下面的方法,直接传递类到后台

三:复杂传值,直接从前台传递一个类到后台接收

我们还是把路由表恢复成以下 
这里写图片描述

4.1 我们先在前台页面,用post方式,来传递一个类的2个值到后台

定义一个简单的类 
这里写图片描述 
我们在前台提交的页面设置 方式为 post 提交 ,地址就指向我们的 webapi地址 
这里写图片描述

由于我们是通过 Post方式提交的数据,那么后台接收的时候,就是用 FromBody 来进行接收,由于刚好我们传递的前台数据就是类的2个字段,那么后台接收的时候,也可以直接用类来接收,webapi会根据类型和字段来帮我们自动加载数据,获取到值.

如果你这里是用 get 方式进行传值的,那么这里的 FromBody 就应该换成 FromUri 
这里写图片描述


这里写图片描述

4.2 用get方式来获取数据

我直接在前台,用一个超链接,里面 指向我们的webapi 并且传递2个值,刚好是我们的UserInfo类的2个属性 
这里写图片描述


这里写图片描述

4.3 即使我们传了一个不存在型别里的属性名称参数值,也不会引发错误,该参数只会被忽略掉

例如,我们修改4.1的例子,在post提交的时候,我们新增加一个 参数,这个参数在后台的 Userinfo类里面是没有对应的属性的,我们这样提交之后,后台接收到值,会自动忽略掉不在类属性里面的值 
这里写图片描述


这里写图片描述 
4.4 最传统 通过 request.form 和 request.querystring 的方式的获取值

我们传统的在 aspx或者是 一般处理程序里面获取值是通过 request.querystring和request.form 来获取到.那么在 webapi里面,则是有些改变

public void Post([FromBody]string value)
         {
             HttpContextBase context = (HttpContextBase)Request.Properties["MS_HttpContext"];//获取传统context
             HttpRequestBase request = context.Request;//定义传统request对象
             string name = request.Form["name"];

         }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里写图片描述 
可以通过上面这种强转的方式获取,也可以直接

var context = HttpContext.Current.Request;  
  • 1
  • 2

WEBAPI中的Request是HttpRequestMessage类型,不能像Web传统那样有querystring和from 方法接收参数,而传统的HttpReqest的基类是HttpReqestBase. 所以这里我们就直接使用(HttpContextBase)Request.Properties[“MS_HttpContext”]

四: 前台调用, ajax 来调用

可以参考 http://www.cnblogs.com/lori/p/3555737.html

参考 : http://tech.it168.com/a2012/0606/1357/000001357231_all.shtml 
这里写图片描述

五: 后台调用,后台代码调用

参考 : http://www.cnblogs.com/joeylee/p/3810721.html

六 : 如果我们想不用 Get/Post/Put/Delete ,怎么定义 ? 简单,我们自己在方法上打上 接受动词标签 HttpPost HttpGet

我们按照 api/{controller}/{id}的格式 
这里写图片描述 
比如我们在 xiaoxin 这个 apicontroller 有自己写的2个方法(注意 他们的参数名是一样的,方法名 不一样) 
这里写图片描述

我们想通过get方法来调用其中一个方法 http://localhost:28160/api/xiaoxin/RequestToken

这个时候就会直接报错 请求的资源不支持 http 方法“GET” 
这里写图片描述


这里写图片描述

再次调用其中的一个方法,并且传递参数过去

http://localhost:28160/api/xiaoxin/AccessToken?name=joey&pwd=lee

居然直接就报错了,提示 : 找到了与该请求匹配的多个操作 
这里写图片描述

这里报错的坑爹原因是: 你以为你刚才那样写 url 是在调用 AccessToken方法? 你太天真了,都说了, 我们的webapi是只绑定到 controller 上,而不绑定到 action上的,调用什么方法,完全看你是用的 post 还是get方法,并且是根据action的名字里面有没有 post和 get 来匹配action的 ,我这里使用url的方式显然是get方法, 然后 AccessToken?name=joey&pwd=lee 这么一大串,在路由里面实际就是代表了参数id, 当匹配到 controller 里面的时候,发现有2个 HttpGet 的方法, 但是 这2个方法,他们的参数名字都是一模一样的,所以就提示了, 找到了与该请求匹配的多个操作….

那么如何修改呢? 
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_33857502/article/details/80351583