在WebAPI对于Action的选择主要经过:Action方法名匹配,Http方法匹配,参数匹配三步。

Http方法匹配

WebAPI提供了三种Http方法的选择方式,分别是:方法前缀,AcceptVerbs特性,HttpXXX特性

方法前缀:

在上一篇中都是采用的这种方式,即将Http方法作为Action的前缀。比如GetAll, PostByUrl。

另外这种方式只能指定一种Http方法,比如GetPutPostAll()只支持GET请求

AcceptVerbs特性

AcceptVerbs特性提供了两个构造函数:

public AcceptVerbsAttribute(params string[] methods)

public AcceptVerbsAttribute(string method)

通过这两个构造函数我们可以为Action的指定Http请求方式,比如:

[AcceptVerbs("POST","PUT")]

public IEnumerable<Figure> PostByBody([FromBody] Figure figure)

这个时候就可以采用Post,Put方式进行访问。

HttpXXX特性

HttpXXX方式跟AcceptVerbs类似,我们可以将其看成是AcceptVerbs的防错误方式(在拼写http方法时可能会出现失误),其格式如下:

[HttpPut]

[HttpPost]

public IEnumerable<Figure> PostByBody([FromBody] Figure figure)

ASP.NET WebAPI定义了7种对应的特性类型:

HttpGet

HttpHead

HttpPut

HttpPost

HttpPatch

HttpOptions

HttpDelete

如果采用了AcceptVerbs与HttpXXX方式,那么前缀方式将失效。AcceptVerbsAttribute与HttpXXXAttribute都实现接口IActionHttpMethodProvider,所以最终的可以采用的Http请求方法是这两种方式的并集。

Action方法名匹配

方法名的匹配因为比较简单,在这里我们来看一下VS2013默认生成的路由模板。

        public static void Register(HttpConfiguration config)
{
// Web API 配置和服务 // Web API 路由
config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}

  

VS2013默认情况下
提供的路由格式为"api/{controller}/{id}",并没有提供action,所以在进行Action查找的时候只会根据请求方式与参数进行匹配。

在Figure中定义两个方法,分别是:

public IEnumerable<Figure> GetAll()

public Figure GetFigure(string firstName)

分别用以下url进行访问:

http://localhost:7075/api/Figure

http://localhost:7075/api/Figure?firstName=Bran

此时他们调用的方法分别是GetAll, GetByQueryString

另外在FigureController再加一个无参无返回值的Get方法,现在再用http://localhost:7075/api/Figure访问就会得到"找到了与该请求匹配的多个操作"的错误消息

参数匹配

在.NET中方法可以重载,所以在Action的选择中也会有对参数的匹配过程。参数的来源于RouteData与QueryString。在匹配中,会出现以下几种情况(为了在):

1.所有参数无默认值

这种情况下就会对所有参数进行匹配,如下:

public Figure GetFromQueryString(string firstName)

public Figure GetFromQueryString(string firstName,string lastName)

用以下Url进行访问

http://localhost:7075/api/Figure/GetByQueryString?firstName=Bran

http://localhost:7075/api/Figure/GetByQueryString?firstName=Bran&lastName=Stack

分别调用的是GetFromQueryString(string firstName), GetFromQueryString(string firstName,string lastName。

但我们使用http://localhost:7075/api/Figure/GetByQueryString进行访问,会返回"404 Not FOUND"。

2.存在默认只参数

首先可以确认的是,优先进行所有参数进行匹配,如果没有匹配的Action再进行二轮匹配

public IEnumerable< Figure> GetFromQueryStringDefaultValue(string lastName="Stack")

public Figure GetFromQueryStringDefaultValue(string firstName, string lastName="Stack")

Action一通过以下url都可以访问

http://localhost:7075/api/Figure/GetFromQueryStringDefaultValue

http://localhost:7075/api/Figure/GetFromQueryStringDefaultValue?lastName=Jon

Action二通过以下Action也都可以访问

http://localhost:7075/api/Figure/GetFromQueryStringDefaultValue?firstName=Bran

http://localhost:7075/api/Figure/GetFromQueryStringDefaultValue?firstName=Bran&lastName=Stack

如果我们将Action二的firstName也设置默认值,那么上面四个url进行访问都和得到"找到了与该请求匹配的多个操作"的错误。

3.参数类型

方法的重载由参数数量、参数类型、参数类型顺序决定,由于Web访问的特殊性(只根据参数名匹配参数)所以参数类型顺序不作为匹配的原则。上面的两种情况都是对参数数量的匹配。在FigureController重载方法GetFromQueryStringType

public string GetFromQueryStringType(string x, string y)

public int GetFromQueryStringType(int x, int y)

通过http://localhost:7075/api/Figure/GetFromQueryStringType?x=1&y=2访问。此时会得到"找到了与该请求匹配的多个操作"。

所以仅仅只通过参数类型(参数名相同)进行重载是不行的。

可以作为Action的方法

  1. 公共的实例方法
  2. 方法不是继承自ApiController

源码

Github: https://github.com/BarlowDu/WebAPI (API_2)

ASP.NET WebAPI 02-Action的选择(一)的更多相关文章

  1. ASP.NET WebAPI 10 Action的选择(二)

    在本系列的第二篇简要的讲述了Action的选择条件本篇深入讲述一下Action选择的过程在上一篇中我们已经讲到了Controller的激活过程中已经说到了设置Controller的Controller ...

  2. ASP.NET WebAPI 12 Action的执行

    Action的激活大概可以分为如下两个步骤:Action对应方法的调用,执行结果的协商.在WebAPI中由HttpActionInvoker(System.Web.Http.Controllers)进 ...

  3. Asp.Net WebApi Action命名中已‘Get’开头问题

    ApiController 中的Action 命名已‘Get’开头,Post方法提交失败 场景: 1.action命名使用Get开头 /// <summary> /// 获取用户的未读消息 ...

  4. WebApi官网学习记录---webapi中controller与action的选择

    如果framework找到一个匹配的URI,创建一个包含占位符值的字典,key就是这些占位符(不包括大括号),value来自URI或者默认值,这个字典存储在IHttpRouteData对象中.默认值可 ...

  5. ASP.NET Web API 框架研究 Action的选择

    如何从HttpController众多方法里如何选择出有效的Action方法?主要分一下几个步骤: 首先,获取候选HttpActionDescriptor列表(ILookup(string,HttpA ...

  6. Asp.Net WebApi核心对象解析(下篇)

    在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...

  7. ASP.NET WebApi 文档Swagger中度优化

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文地址:www.cnblogs.com/tdws   写在前面 在后台接口开发中,接口文档是必不可少的.在复杂的业务当中和多人对接的情况下,简 ...

  8. 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi

    一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...

  9. 前端angularjs+requirejs+dhtmlx 后端asp.net webapi

    享一个前后端分离方案源码-前端angularjs+requirejs+dhtmlx 后端asp.net webapi   一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家 ...

随机推荐

  1. Ubuntu配置vncserver

    https://help.aliyun.com/knowledge_detail/59330.html 首先,安装桌面环境和vnc4server: sudo apt-get install gnome ...

  2. poppo大根堆的原理与实现。

    大根堆的定义:1 大根堆是一个大根树 2 大根堆是一个完全二叉树 所以大根堆用数组表示是连续的,不会出现空白字段. 对于大根堆的插入 对于大根堆的插入,可以在排序前确定大根堆的形状,可以确定元素5从位 ...

  3. 单例 ------ C++实现

    基础知识掌握: 单例考虑三点:内存何时释放.运行速度如何.多线程下能否保证只有一个实例 如果获取对象的返回值类型是引用,返回值赋值给变量而不是引用会进行对象的拷贝,这样就会出现两个对象,可以把显示声明 ...

  4. [吴恩达机器学习笔记]13聚类K-means

    13.聚类 觉得有用的话,欢迎一起讨论相互学习~Follow Me 13.1无监督学习简介 从监督学习到无监督学习 在一个典型的监督学习中,我们有一个有标签的训练集,我们的目标是找到能够区分正样本和负 ...

  5. CIFAR10/CIFAR100数据集介绍

    CIFAR-10/CIFAR-100数据集解析 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 CIFAR-10/CIFAR-100数据集 CIFAR-10和CIFAR-100被标记 ...

  6. SpringCloud学习(2)——Rest微服务案例

    创建父工程: microservicecloud  创建公共模块api:microservicecloudapi SQL脚本: 此学习路线总共创建3个库, 分别为clouddb01, clouddb0 ...

  7. JAVA Thread Dumps 三部曲

    一.windows环境下方法 1:cmd下找到运行服务器容器的PID jps -v 例: C:\Users\Administrator>jps -v4856 Bootstrap -Djdk.tl ...

  8. Emacs ^ Vim

    Emacs存活: http://files.cnblogs.com/files/TheRoadToTheGold/Emacs%E2%80%94%E2%80%94%E5%AD%98%E6%B4%BB.z ...

  9. 2017 ACM Arabella Collegiate Programming Contest(solved 11/13)

    省选考前单挑做点ACM练练细节还是很不错的嘛- 福利:http://codeforces.com/gym/101350 先来放上惨不忍睹的virtual participate成绩(中间跑去食堂吃饭于 ...

  10. [转]标准C++中的string类的用法总结

    原文地址:http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html 相信使用过MFC编程的朋友对CString这个类的印象应该非常 ...