• 周五. 3月 29th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

MVC4 的 Web API 接口

admin

11月 28, 2021

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

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注