Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc MVC WebApi中的方法如何映射到http谓词?_Asp.net Mvc_Asp.net Mvc Routing_Asp.net Web Api - Fatal编程技术网

Asp.net mvc MVC WebApi中的方法如何映射到http谓词?

Asp.net mvc MVC WebApi中的方法如何映射到http谓词?,asp.net-mvc,asp.net-mvc-routing,asp.net-web-api,Asp.net Mvc,Asp.net Mvc Routing,Asp.net Web Api,在下面链接的5分钟视频中,在1:10处,Jon Galloway说,按照惯例,将名为DeleteComment的方法添加到他的CommentsController类将自动映射到delete http谓词 MVC和WebApi如何知道如何将方法路由到正确的谓词?我知道global.asax.cs文件中的路由将请求路由到正确的控制器,但是删除请求如何“按约定映射”到delete方法或任何方法?特别是当每个动词可以有一个以上的方法时?“按惯例”让我觉得它只是在看方法名称中的第一个单词。。。但如果是这样

在下面链接的5分钟视频中,在1:10处,Jon Galloway说,按照惯例,将名为DeleteComment的方法添加到他的CommentsController类将自动映射到delete http谓词

MVC和WebApi如何知道如何将方法路由到正确的谓词?我知道global.asax.cs文件中的路由将请求路由到正确的控制器,但是删除请求如何“按约定映射”到delete方法或任何方法?特别是当每个动词可以有一个以上的方法时?“按惯例”让我觉得它只是在看方法名称中的第一个单词。。。但如果是这样,它必须读取方法的签名才能区分两个delete方法或两个get方法。。。这一切的定义是什么

视频:

谢谢

编辑: 下面是WebApi模板中的示例ValuesController类中的代码。这就是我最初问题的来源。区分这些方法(以及控制器中的任何其他方法)的“约定”是如何工作的

//GET/api/values
公共IEnumerable Get()
{
返回新字符串[]{“value1”,“value2”};
}
//获取/api/values/5
公共字符串Get(int-id)
{
返回值;
}

这种情况经常出现。对此有不同的看法。我个人目前还没有订阅任何特定的想法,但似乎每个资源有一个控制器的想法在REST社区中最受欢迎

所以基本上你可以:

  • 公开路线中的操作(Web API将单词
    action
    视为类似于MVC),但通常不打算使用它
  • 根据此定义具有不同参数的方法
  • 正如我所说,最推荐的方法是每个资源使用一个控制器。因此,即使在WebAPI示例中,实体集合的控制器与实体本身的控制器也是不同的。阅读罗伯·科纳利的这篇文章,这是格伦的答案

  • 我提前道歉,这篇文章有点偏离了你的要求,但当我读到你的问题时,所有这些都冒了出来

    WebAPI匹配语义
    WebAPI(中的默认路由)使用的匹配语义相当简单

  • 它将动作的名称与动词匹配(动词=GET?查找以“GET”开头的方法名称)
  • 如果传递了一个参数,api将使用一个参数查找一个操作
  • 因此,在代码示例中,不带参数的GET请求与不带参数的
    GET*()
    函数匹配。包含and ID的Get查找
    Get***(int ID)

    示例
    虽然匹配的语义很简单,但它会给MVC开发人员(至少这个开发人员)带来一些混乱。让我们看一些例子:

    奇数名称-get方法可以命名为任何名称,只要它以“get”开头。因此,对于小部件控制器,您可以将函数命名为
    get草莓()
    ,它仍然是匹配的。可以将匹配想象为:
    methodname.StartsWith(“Get”)

    多个匹配方法-如果有两个没有参数的Get方法,会发生什么
    get草莓()
    GetOrange()
    。据我所知,代码中首先定义的函数(文件顶部)获胜……奇怪。这样做的副作用是使控制器中的某些方法无法访问(至少在默认路由下)…陌生人

    注意:测试版的表现与上述“匹配多种方法”相同——RC&Release版本更具强迫性。如果存在多个可能的匹配项,则会抛出错误。此更改消除了多个不明确匹配的混淆。同时,它降低了我们在同一控制器中混合REST和RPC风格接口的能力,这依赖于顺序和重叠路由

    怎么办?
    好吧,WebAPI是新的,共识仍在凝聚。社区似乎在很大程度上达到了休息的原则。然而,并不是每个API都可以或者应该是RESTful的,有些API更自然地以RPC样式表示。休息&人们称之为休息的东西似乎是

    作为一个实用主义者,我怀疑许多API将是70%RESTful的,带有少量RPC风格的方法。首先,仅控制器的扩散(给定webapi绑定方法)就会让开发人员发疯。其次,WebAPI实际上没有一种内置的方法来创建api路径的嵌套结构(这意味着:
    /api/controller/
    很容易,但是
    /api/CATEGORY/Sub-CATEGORY/controller
    是可行的,但是很痛苦)

    从我的角度来看,我希望看到webAPI文件夹结构控制默认的API路径。。。这意味着如果我在UI项目中创建一个Category文件夹,那么默认路径将是
    /api/Category

    我做了什么?
    因此,我有一些要求:(1)在大多数情况下能够使用restful语法,(2)在控制器(想想子文件夹)之间有一些“名称空间”分隔,(3)必要时能够调用其他类似rpc的方法。实现这些需求归结为巧妙的路由

    // SEE NOTE AT END ABOUT DataToken change from RC to RTM
    
    Route r;
    r = routes.MapHttpRoute( name          : "Category1", 
                             routeTemplate : "api/Category1/{controller}/{id}", 
                             defaults      : new { id = RouteParameter.Optional } );
    r.DataTokens["Namespaces"] = new string[] {" UI.Controllers.Category1"};
    
    r = routes.MapHttpRoute( name          : "Category2", 
                             routeTemplate : "api/Category2/{controller}/{id}", 
                             defaults      : new { id = RouteParameter.Optional } );
    r.DataTokens["Namespaces"] = new string[] {" UI.Controllers.Category2"};
    
    routes.MapHttpRoute(     name          : "ApiAllowingBL", 
                             routeTemplate : "api/{controller}/{action}/{id}",
                             defaults      : new { id = RouteParameter.Optional } );
    
    routes.MapHttpRoute(     name          : "DefaultApi",  
                             routeTemplate : "api/{controller}/{id}",           
                             defaults      : new { id = RouteParameter.Optional } );
    
    • 前两条路由创建“子文件夹”路由。我需要为每个子文件夹创建一个路由,但我将自己限制在主要类别中,因此我只得到其中的3-10个。注意这些路由如何添加
      名称空间
      数据标记,以限制为特定路由搜索哪些类。这与向UI项目添加文件夹时的典型名称空间设置很好地对应
    • 第三条路径允许调用特定的方法名(如传统的mvc)。由于WebAPI去掉了URL中的操作名称,因此相对容易判断哪些调用需要此路由
    • l
      // SEE NOTE AT END ABOUT DataToken change from RC to RTM
      
      Route r;
      r = routes.MapHttpRoute( name          : "Category1", 
                               routeTemplate : "api/Category1/{controller}/{id}", 
                               defaults      : new { id = RouteParameter.Optional } );
      r.DataTokens["Namespaces"] = new string[] {" UI.Controllers.Category1"};
      
      r = routes.MapHttpRoute( name          : "Category2", 
                               routeTemplate : "api/Category2/{controller}/{id}", 
                               defaults      : new { id = RouteParameter.Optional } );
      r.DataTokens["Namespaces"] = new string[] {" UI.Controllers.Category2"};
      
      routes.MapHttpRoute(     name          : "ApiAllowingBL", 
                               routeTemplate : "api/{controller}/{action}/{id}",
                               defaults      : new { id = RouteParameter.Optional } );
      
      routes.MapHttpRoute(     name          : "DefaultApi",  
                               routeTemplate : "api/{controller}/{id}",           
                               defaults      : new { id = RouteParameter.Optional } );
      
      r.AddRouteToken("Namespaces", new string[] {"UI.Controllers.Category1"});
      
      private static Route AddRouteToken(this Route r, string key, string[] values) {
        //change from RC to RTM ...datatokens is null
      if (r.DataTokens == null) {
             r.DataTokens = new RouteValueDictionary();
          }
          r.DataTokens[key] = values;
          return r;
      }
      
      private static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, string[] namespaceTokens)
      {   
          HttpRouteValueDictionary    defaultsDictionary      = new HttpRouteValueDictionary(defaults);
          HttpRouteValueDictionary    constraintsDictionary   = new HttpRouteValueDictionary(constraints);
          IDictionary<string, object> tokens                  = new Dictionary<string, object>();
                                      tokens.Add("Namespaces", namespaceTokens);
      
          IHttpRoute route = routes.CreateRoute(routeTemplate, defaultsDictionary, constraintsDictionary, dataTokens: tokens, handler:null);
          routes.Add(name, route);
      
          return route;
      }