mvc4中的 webapi 的使用方式

目录

一:简单介绍什么是Web api

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

三:简单使用,直接从前台传递一个类到后台接收

四:其他获取值的方式

 

一:简单介绍什么是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模板自动创建的演示文件进行分析

image

从演示的列子,我们可以看到在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<T> 的方法,等于我们拥有了强类型。

我们再来看看默认的 api 路由表

image

这里,只注册到了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。

 

另外我们可以注意到在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 }
        );

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

public string Get(String p1, String p2)
        {
            return p1 + "/" + p2;
        }

我们去调用一下试试   image

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

 

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

我们还是把路由表恢复成以下

image

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

定义一个简单的类

image

我们在前台提交的页面设置 方式为 post 提交 ,地址就指向我们的 webapi地址

image

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

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

image

image

 

4.2 用get方式来获取数据

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

image

image

 

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

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

image

image

 

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"];
 
         }
复制代码

 

image

可以通过上面这种强转的方式获取,也可以直接

  1. var context = HttpContext.Current.Request;  

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

image

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

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

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

我们按照 api/{controller}/{id}的格式 

image

比如我们在 xiaoxin 这个  apicontroller 有自己写的2个方法(注意 他们的参数名是一样的,方法名 不一样)

image

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

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

image

如果说我们使用的方法名称不是 Get/Post/Put/Delete 的规则时,那么我们就一定要宣告它的接受动词 (Accept Verb),所以我们可以修改如下代码:

image

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

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

居然直接就报错了,提示  :  找到了与该请求匹配的多个操作

image

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

那么如何修改呢?

image

posted @ 2016-08-03 15:07  .NET-蜕变  阅读(14006)  评论(4编辑  收藏  举报