zoukankan      html  css  js  c++  java
  • MVC4 的 Web API 接口

    https://www.cnblogs.com/hefeilong/p/5732992.html

     

    目录

    一:简单介绍什么是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 ,这个刚好符合 Web API 的约定的,什么约定呢?

    你调用什么类型的方法,例如  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名称是有约定的。

    Web API 大约有这样的约定:     

    • action名称以Get开头,0个参数,匹配路由到 /控制器,例如:public IEnumerable<string> Get();
    • action名称以Get开头,1个参数,匹配路由到 /控制器/id,例如:public string Get(int id);
    • action名称以Post开头,1个参数,匹配路由到post方式的 /控制器,例如:public void Post([FromBody]string value);

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

    另外Post、Put方法的参数中有一个关键字[FromBody],而Get、Delete则没有,如果没有说明[ FromBody ]就默认为[FromUri ]

    [FromBody]表示从请求本体取数据,就像一般表单Post Submit一样,而 [FromUri] 则表示由URI中取数据,就像在网址列中的所夹带的参数。

    三、通过URL传递参数

     3.1、Get方法只有一个id参数:FromUri

    在Web API的示范代码里,Get方法很简单,只有一个id参数,并且是简单的int型,因此我们可以用  http://localhost/api/Values/1 这样的请求执行Get(int id)方法;

    说明:

    1:如果用传统的方法在URL中给出参数,则 http://localhost/api/Values?id=1,如果这里id和方法中的参数名称不同则会出错,而采用这种REST原则,URL中只有参数占位符,不需要参数名称。

    2:关于Web API的路由模板的设置:

     路由模板中的占位符名称是id,控制器方法的参数也是id , 如下:

    测试结果:

    占位符名称测试结果:路由模板中的占位符名称可以随意取,只要和控制器方法中的参数名称一样即可。

     

    3.2、Get方法有多个参数:FromUri

    如果方法需要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

    这种方法虽然比较简单,但是如果参数比较多,这种方法就比较麻烦,这时可以采用传递类的方法。

    3.3、Request.RequestContext.RouteData.Values["参数名"]获取路由配置中参数的值.

     如果路由配置如下:

    则可以用 Request.RequestContext.RouteData.Values["id"].ToString()取id数据,但是不能用 Request.RequestContext.RouteData.Values["name"]取数,因为"name"不在路由配置中,并且生成的url会把name参数放到"?"后,

    例如:如:  http://loclahost/home/index/123?name=gou

    3.4、后台以类接收get数据

    后台定义类

    image

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

    image

    四、通过类传递参数:FromBody

    把路由表恢复成如下:

    image

    4.1、前端以post方式传递多个数据,地址指向我们的 web api地址:

    image

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

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

    4.2、 后台以类接收post数据

    前台以 post 方式提交,地址指向我们的 webapi地址 /api/xiaoxin/。

    image

     4.3、后台以类接收数据,前端数据名称不在类定义中

    如下,添加一个Other 参数,这个参数在后台的 Userinfo类里没有对应的属性,后台接收到数据后,自动忽略掉不在类属性里面的值。

    image

    image

     4.4、通过传统的 request.form  和  request.querystring 的方式的获取前端数据

    Request.Form:获取以POST方式提交的数据(接收Form提交来的数据);

    Request.QueryString:获取地址栏参数(以GET方式提交的数据)

    Request:包含以上两种方式(优先获取GET方式提交的数据),它会在QueryString、Form、ServerVariable中都搜寻一遍。

    传统的在 aspx或者是一般处理程序里面获取值是通过 request.querystring和request.form 来获取数据,但在 web api取数有些改变。

     image

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

    也可以直接用: var context = HttpContext.Current.Request;  

    五、前台调用, 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

    七 、用HttpPost  HttpGet修饰action名称

    如果我们想不用 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

  • 相关阅读:
    台州 OJ 3847 Mowing the Lawn 线性DP 单调队列
    洛谷 OJ P1417 烹调方案 01背包
    快速幂取模
    台州 OJ 2649 More is better 并查集
    UVa 1640
    UVa 11971
    UVa 10900
    UVa 11346
    UVa 10288
    UVa 1639
  • 原文地址:https://www.cnblogs.com/wfy680/p/15148635.html
Copyright © 2011-2022 走看看