webapi路由规则 不使用id_webapi 中post请求的路由规则 - CSDN
精华内容
参与话题
  • WebApi路由机制详解——看完不会用你打我

    万次阅读 多人点赞 2020-10-11 17:15:02
    随着前后端分离的大热,WebApi在项目中的作用也是越来越重要,由于公司的原因我之前一直没有机会参与前后端分离的项目,但WebApi还是要学的呀,因为这东西确实很有用,可单独部署、与前端和App交互都很方便,既然有...

    随着前后端分离的大热,WebApi在项目中的作用也是越来越重要,由于公司的原因我之前一直没有机会参与前后端分离的项目,但WebApi还是要学的呀,因为这东西确实很有用,可单独部署、与前端和App交互都很方便,既然有良好的发展趋势,我们当然应该顺势而为——搞懂WebApi!Restful相当于给Http请求增加了语义,Post(增)、Delete(删)、Put(改)、Get(查),有时会用Get进行查询,用Post进行增、删、改。

    从MVC到WebApi,路由机制一直都在其中扮演着重要的角色。

    它可以很简单:如果你只需要会用一些简单的路由,如/Home/Index那么你只需要配置一个默认路由就能搞定。

    它可以很神秘:你的url可以千变万化,看到一些“无厘头”的url,很难理解它是如何找到匹配的Action,例如/api/Pleasure/1/detail,这样的url可以让你纠结半天。

    它可以很深奥:当面试官提问“请简单分析下MVC路由机制的原理”,你可能事先就准备好了答案,然后劈里啪啦一顿(型如:UrlRoutingMoudle—>Routes—>RouteData—>RequestContext—>Controller),你可能回答的很流利,但并不一定理解这些个对象到底是啥意思。):目前为止我还没能理解透,以后会继续努力的直到弄清楚。

    一、MVC和WebApi路由机制比较

    1、MVC使用的路由

    在MVC中,默认路由机制是通过解析url路径来匹配Action。比如:/User/GetList,这个url就表示匹配User控制器下的GetList方法,这是MVC路由的默认解析方式。为什么默认的解析方式是这样子的呢?因为MVC定义了一个默认路由,路由代码放在App_Start文件夹下的RouteConfig.cs中,今后我们如果想要自定义路由规则,那自定义路由的代码也要写在RouteConfig.cs中。

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

    url:"{controller}/{action}/{id}"定义了路由解析规则,{controller}是必填参数默认值是Home,{action}是必填参数默认值是Index,{id}表示匹配名称为id的形参,而且是可选参数(方法的参数列表中可以有名为id的形参,也可以没有)。

    2、WebApi使用的路由

    在WebApi中,默认路由机制是通过解析http请求的类型来匹配Action,也就是说WebApi的默认路由机制不需要指定Action的名称。比如:/api/Pleasure,这个url就表示匹配Pleasure控制器下的[HttpGet]方法,/api是固定必填值,这是WebApi路由的默认解析方式。WebApi的默认解析方式之所以如此,同样也是因为定义了默认路由,路由代码放在App_Start文件夹下的WebApiConfig.cs中,今后我们如果想要自定义路由规则,那自定义路由的代码也要写在WebApiConfig.cs中。

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

    routeTemplate:"api/{controller}/{id}"定义了路由解析规则,api是固定必填值,{controller}是必填参数无默认值,{id}表示匹配名称为id的形参,而且是可选参数(方法的参数列表中可以有名为id的形参,也可以没有)。

    3、MVC和WebApi路由区别汇总

    • WebApi的默认路由机制通过http请求的类型匹配Action,MVC的默认路由机制通过url匹配Action
    • WebApi的路由配置文件是WebApiConfig.cs,MVC的路由配置文件是RouteConfig.cs
    • WebApi的Controller继承自Web.Http.ApiController,MVC的Controller继承自Web.Mvc.Controller

    4、示例一

    public class PleasureController : ApiController
    {
        [HttpGet]
        public IEnumerable<string> GetOne()
        {
            return new string[] { "value1", "value2" };
        }
    }

     
    为什么http://localhost:7866/api/Pleasure能匹配到GetOne()方法呢?首先根据路由规则解析出控制器是Pleasure,其次通过浏览器地址栏直接发出的请求都是get请求而Pleasure中只有一个get类型的方法,因此就匹配到了GetOne()。


    为什么http://localhost:7866/api/Pleasure/1也能匹配到GetOne()方法呢?因为id是可选形参,即使指定了id的值,也可以访问不含形参id的方法。

    5、示例二

    public class PleasureController : ApiController
    {
        [HttpGet]
        public IEnumerable<string> GetOne()
        {
            return new string[] { "value1", "value2" };
        }
    
        [HttpGet]
        public IEnumerable<string> GetOne(int id)
        {
            return new string[] { "含参-value1", "含参-value2" };
        }
    }


    示例二中http://localhost:7866/api/Pleasure请求的结果与示例一中的结果是一样的,在此不做过多的解释。

    示例二中http://localhost:7866/api/Pleasure/1请求到了含参方法,说明如果指定了形参id的值,而且Controller中存在指定请求类型的含参方法,会优先匹配含此形参的方法。若匹配不上含参方法,但参数类型为可选参数,那就再尝试匹配不含此形参的方法。

    6、示例三

    public class PleasureController : ApiController
    {
        [HttpGet]
        public IEnumerable<string> GetOne()
        {
            return new string[] { "value1", "value2" };
        }
    
        [HttpGet]
        public IEnumerable<string> GetOne(int id)
        {
            return new string[] { "含参-value1", "含参-value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "value";
        }
    }


    虽然WebApi的默认路由机制不需要指定Action,但是WebApi支持在url中指定Action。由于Restful风格的服务要求请求的url中不能包含Action,因此WebApi不提倡在url中指定Action。

    7、示例四

    public class PleasureController : ApiController
    {
        [HttpGet]
        public string GetOne(int id,string name,int age)
        {
            return string.Format("id={0},name={1},age={2}", id, name, age);
        }
    }

     

    二、WebApi基础

    1、默认路由

    新建WebApi服务的时候,会自动在WebApiConfig.cs文件里面生成一个默认路由:

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

    将MapHttpRoute()方法转到定义可以发现,它有四个重载方法:

    下面来看看各个参数的作用:

    • name:"DefaultApi"表示此路由的名称。注册多个路由时必须保证名称不重复。
    • routeTemplate:"api/{controller}/{id}"表示路由的匹配规则。api是固定必填值,这个值是可变的如果你把它改成“BalaApi”,那url就应该变成 “http://1.1.1.1:80/BalaApi/***”。{controller}是控制器的占位符,在真实的url中,该部分对应的是具体的控制器名称,这个和MVC一致。{id}是形参id的占位符,id是形参的名字,一般这个参数都会在defaults中设置为可选。
    • defaults:new { id=RouteParameter.Optional }表示设置id为可选参数,routeTemplate中的{controller}和{id}都可以设置默认值。若defaults改成new { controller="Pleasure", id = RouteParameter.Optional },那么我们请求http://1.1.1.1:80/api这个url仍然能访问到Pleasure控制器中的[HttpGet]方法。
    • constraints:new{ id = @"\d+" }表示为id添加约束。形参id不能为空而且必须是整数,优先匹配含参方法,也能匹配无参方法(详情请回看上一部分的示例一)。
    public class PleasureController : ApiController
    {
        [HttpGet]
        public IEnumerable<string> GetOne()
        {
            return new string[] { "value1", "value2" };
        }
    
        [HttpGet]
        public IEnumerable<string> GetOne(int id)
        {
            return new string[] { "含参-value1", "含参-value2" };
        }
    }



     我们如果想在不指定id值的时候仍然能够正常请求到GetOne(),把id的约束改成“constraints: new { id = @"\d*" }”即可,这里就不放截图了,大家可以自己去试试。我们只在路由中对id的值进行了约束,其实我们也可以约束Controller和Action,但一般不常用大家有兴趣可以自己玩一下。

    2、自定义路由

    上面介绍了许多关于默认路由的内容,除此之外我们还可以自定义路由,比如将WebApiConfig.cs改成下面这样:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 路由
            config.MapHttpAttributeRoutes();
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
    
            config.Routes.MapHttpRoute(
                name: "ActionApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

    2.1、自定义匹配到Action的路由

    这个自定义路由很好理解,它和MVC中的默认路由大致相同,不同之处是此路由多了个api前缀。
    添加了可匹配到Action的路由后,就能解决“第一部分->示例三”中遇到的问题了。
    当同时存在多个路由时,一定要注意name不能重复。

    public class PleasureController : ApiController
    {
        [HttpGet]
        public IEnumerable<string> GetOne()
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public IEnumerable<string> GetOne(int id)
        {
            return new string[] { "GetOne(int id)->value1", "GetOne(int id)->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }



    我艹,为什么http://localhost:7866/api/Pleasure/GetOne请求失败了,为什么没有匹配上GetOne()方法?
    下面我来解释下,DefaultApi定义在ActionApi之前,所以先检查http://localhost:7866/api/Pleasure/GetOne能否与DefaultApi匹配成功,api是固定必填值,Pleasure是controller的值,GetOne是id的值,匹配成功!然后去PleasureController中找[HttpGet]类型而且含有string id形参的方法,当然是没有啦。只找到一个[HttpGet]类型的GetOne(int id),所以错误信息中提示参数id的类型不匹配。

    接下来说说解决方法,实际上id是int类型的参数,我们希望GetOne能匹配上ActionApi中的action,而不是DefaultApi中的id,这在默认情况下是做不到的,不过为DefaultApi中的id加上个约束后就能做到了,路由修改后如下:

    public static void Register(HttpConfiguration config)
    {
        // Web API 路由
        config.MapHttpAttributeRoutes();
    
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new { id = @"\d*" }
        );
    
        config.Routes.MapHttpRoute(
            name: "ActionApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }

     


    2.2、修改方法的ActionName

    WebApi默认GetOne()方法的ActionName就是GetOne,如果我们想要方法名和ActionName不一致,可以通过ActionName特性来修改。

    public class PleasureController : ApiController
    {
        [ActionName("NewGetOne")]
        [HttpGet]
        public IEnumerable<string> GetOne()
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public IEnumerable<string> GetOne(int id)
        {
            return new string[] { "GetOne(int id)->value1", "GetOne(int id)->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }


     

    三、WebApi路由执行过程

    1、路由原理

    有了上面的理论作为基础,我们再来分析WebApi路由机制的原理以及路由匹配的过程。由于WebApi的路由机制和MVC有许多相似性,所以要想理解WebApi的路由机制,就需要搬出那些Asp.Net Routing里面的对象。这个过程有点复杂,我就根据搜罗的资料和自己的理解 ,提一些主要的过程:

    a、WebApi服务启动之后,会执行全局配置文件Global.asax.cs的 protected void Application_Start() 方法,其中的 GlobalConfiguration.Configure(WebApiConfig.Register); 会通过委托的方式执行WebApiConfig.cs中的 public static void Register(HttpConfiguration config),将配置的所有路由信息添加到HttpRouteCollection对象中保存起来。这里的HttpRouteCollection对象的实例名是Routes,这个很重要,后面会用到。

    b、当我们发送请求到WebApi服务器的时候,比如当我们访问http://localhost:7866/api/Pleasure时,首先请求会被UrlRoutingModule监听组件截获,然后按照定义顺序检查url能匹配上Routes集合中的哪个路由模板(如果都匹配不上,则返回404),最后返回对应的IHttpRoute对象。IHttpRoute对象是url匹配上的Routes集合里面的一个实体。

    c、将IHttpRoute对象交给当前的请求上下文对象RequestContext处理,根据IHttpRoute对象中的url匹配到对应的controller,然后根据http请求的类型和参数找到对应的action。这样就能找到请求对应的controller和action了。

    这个过程是非常复杂的,为了简化,我只选择了最主要的几个过程。更详细的路由机制可以参考http://www.cnblogs.com/wangiqngpei557/p/3379095.html,这篇文章写得有些深度,感兴趣的朋友可以看下。

    2、根据请求的url匹配路由模板

    通过上文路由过程的分析,我们知道一个请求过来之后,路由主要经历三个阶段:
    1、根据请求的url匹配路由模板
    2、找到controller
    3、找到action

    第一步很简单,主要就是将url与路由模板中配置的routeTemplate进行匹配校验,在此不做过多的说明。

    3、找到controller

    你如果反编译路由模块的代码,就会发现控制器的选择主要在IHttpControllerSelector接口中的SelectController()方法里面处理。

    该方法所需的HttpRequestMessag参数,是由当前请求封装而来,返回HttpControllerDescriptor对象。这个接口默认由DefaultHttpControllerSelector类提供实现。

    默认实现的方法里面大致的算法机制是:首先在路由字典中找到实际的控制器名称(比如“Pleasure”),然后在此控制器名称后面加上“Controller”字符串得到控制器的全称“PleasureController”,最后找到WebApi对应的Controller再实例化就得到当前请求的控制器对象。
     

    4、找到action

    得到了控制器对象之后,Api引擎通过调用IHttpActionSelector接口中的SelectAction()方法去匹配action。这个过程主要包括:

    • 解析当前http请求,得到请求类型(post、delete、put、get)
    • 如果路由模板配置了{action},则直接去url中找action的名称
    • 解析请求的参数

    如果路由模板配置了{action},那么直接去url中找对应的action即可。如果没有配置action,则会首先匹配请求类型(post/delete/put/get),然后匹配请求参数,才能找到对应的action。
     

    5、设置方法同时支持多种http请求类型

    WebApi提供了AcceptVerbs,应用这一特性可以使方法同时支持多种请求类型。这一特性在实际中使用不是太多,大家了解即可。

    [AcceptVerbs("get","post")]
    public string GetList()
    {
        return "GetList()->value";
    }

    四、WebApi特性路由

    如果http请求的类型相同(比如都是get请求),并且请求的参数也相同。这个时候似乎就有点不太好办了,这种情况在实际项目中还是比较多的,比如:

    public class PleasureController : ApiController
    {
        [HttpGet]
        public IEnumerable<string> GetOne()
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }

     当然这个问题可以通过添加匹配到Action的路由来解决,不过这就不符合Restful风格了,所有我们不提倡这种写法。除此之外,利用特性路由也能解决上述问题,下面说说特性路由的东西。

    1、启动特性路由

    public static void Register(HttpConfiguration config)
    {
        //启动特性路由
        config.MapHttpAttributeRoutes();
    
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new { id = @"\d*" }
        );
    
        config.Routes.MapHttpRoute(
            name: "ActionApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }

    一般情况下通过新版本的VS2017创建WebApi项目时,这句话默认已经存在。

    2、最简单的无参特性路由


    2.1、为GetOne()方法添加Route特性(特性路由没参数,GetOne()方法也没参数)

    public class PleasureController : ApiController
    {
        [Route("Pleasure/GetOne")]
        [HttpGet]
        public IEnumerable<string> GetOne()
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }




    结论:

    • 为GetOne()添加了特性路由后,无法通过WebApi默认路由机制(不指定Action)访问GetOne()
    • 为GetOne()添加了特性路由后,无法通过指定ActionName的方式访问GetOne()
    • 为GetOne()添加了特性路由后,只能通过特性路由的路径访问GetOne()

    2.2、为GetOne()方法添加Route特性(特性路由没参数,GetOne()方法有参数)

    public class PleasureController : ApiController
    {
        [Route("Pleasure/GetOne")]
        [HttpGet]
        public IEnumerable<string> GetOne(int age)
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }

    public class PleasureController : ApiController
    {
        [Route("Pleasure/GetOne")]
        [HttpGet]
        public IEnumerable<string> GetOne(string name)
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }



    特性路由不含参数时的结论:

    • 方法没参数时,只要url满足特性路由的定义就能访问到方法
    • 方法有参数时,必须url满足特性路由的规则而且指定了方法所需的参数值才能访问到方法

    3、含参特性路由

    3.1、特性路由有参数,方法没参数

    public class PleasureController : ApiController
    {
        [Route("Pleasure/GetOne/{name}")]
        [HttpGet]
        public IEnumerable<string> GetOne()
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }



    3.2、特性路由有参数,方法有参数

    public class PleasureController : ApiController
    {
        [Route("Pleasure/GetOne/{name}")]
        [HttpGet]
        public IEnumerable<string> GetOne(string name)
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }


     

    public class PleasureController : ApiController
    {
        [Route("Pleasure/GetOne/{name}")]
        [HttpGet]
        public IEnumerable<string> GetOne(string address)
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }



     

    特性路由含参数时的结论:

    • 方法没参数时,只要url满足特性路由的定义就能访问到方法
    • 方法有参数时,必须url满足特性路由的规则而且指定了方法所需的参数值才能访问到方法

    3.3、特性路由有参数,参数在最后而且有默认值

    public class PleasureController : ApiController
    {
        [Route("Pleasure/GetOne/{age:int=16}")]
        [HttpGet]
        public IEnumerable<string> GetOne(int age)
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }



    3.4、特性路由有参数,参数在中间而且有默认值

    public class PleasureController : ApiController
    {
        [Route("Pleasure/{age:int=16}/GetOne")]
        [HttpGet]
        public IEnumerable<string> GetOne(int age)
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }




    4、路由前缀

    在正式项目中,同一个控制器中所有的action的特性路由最好有一个相同的前缀,这并非是必须的,但能增加url的可读性。一般的做法是在控制器上使用[RoutePrefix]特性来标识。当我们使用特性路由来访问时,前边必须加上定义的前缀。

    [RoutePrefix("api/prefix")]
    public class PleasureController : ApiController
    {
        [Route("Pleasure/GetOne/{age:int=16}")]
        [HttpGet]
        public IEnumerable<string> GetOne(int age)
        {
            return new string[] { "GetOne()->value1", "GetOne()->value2" };
        }
    
        [HttpGet]
        public string GetList()
        {
            return "GetList()->value";
        }
    }


    五、总结

    整理这篇文章真是不太容易,如果这篇文章对你有帮助,请点赞、评论支持下。

    特别感谢https://www.cnblogs.com/landeanfen/p/5501490.html,本文的创作灵感来自上述参考,我对其中的内容进行了整理和扩展,感谢博主的无私分享。

    展开全文
  • C# 搭建一个简单的WebApi项目

    万次阅读 多人点赞 2018-12-21 18:10:45
    一、创建Web API1、创建一个新的web API项目启动VS 2013,并在“开始页”选择“新项目”。或从“文件”菜单选择“新建”,然后选择“项目”。在“模板”面板中选择“已安装模板”,并展开“Visual C#”节点。选择该...

    WebApi相关文章:

    一、创建Web API

    1、创建一个新的web API项目

    启动VS 2013,并在“开始页”选择“新项目”。或从“文件”菜单选择“新建”,然后选择“项目”。

    在“模板”面板中选择“已安装模板”,并展开“Visual C#”节点。选择该节点下的“Web”。在项目模板列表中选择“ASP.NET MVC 4 Web应用程序”。
    这里写图片描述
    在“新的ASP.NET MVC 4项目”对话框中选择“Web API”
    这里写图片描述

    二、Web API路由配置

    1、创建好项目后,文件目录如下:
    这里写图片描述

    2、打开App_Start文件夹下的 WebApiConfig.cs 文件
    默认路由配置信息为:
    WebApi的默认路由是通过http的方法(get/post/put/delete)去匹配对应的action,也就是说webapi的默认路由并不需要指定action的名称。

    // Web API 路由
    config.MapHttpAttributeRoutes();
    
     config.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{id}",
         defaults: new { id = RouteParameter.Optional }
     );
    

    我们自定义一个路由配置:

    //自定义路由:匹配到action
    config.Routes.MapHttpRoute(
        name: "ActionApi",
        routeTemplate: "actionapi/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
    

    url: "{controller}/{action}/{id}"这个定义了我们url的规则,{controller}/{action}定义了路由的必须参数,{id}是可选参数

    三、创建Web API方法

    1、在Controllers文件夹下新建一个控制器类,添加一个post请求

    public class UserInfoController : ApiController
    {
    	//检查用户名是否已注册
    	private ApiTools tool = new ApiTools();
    	[HttpPost]
    	public HttpResponseMessage CheckUserName(string _userName )
    	{
    	    int num = UserInfoGetCount(_userName);//查询是否存在该用户
    	    if (num > 0)
    	    {
    	        return tool.MsgFormat(ResponseCode.操作失败, "不可注册/用户已注册", "1 " + userName);
    	    }
    	    else
    	    {
    	        return tool.MsgFormat(ResponseCode.成功, "可注册", "0 " + userName);
    	    }
    	}
    	
    	private int UserInfoGetCount(string username)
            {
                //return Convert.ToInt32(SearchValue("select count(id) from userinfo where username='" + username + "'"));
                return username == "admin" ? 1 : 0;
            }
    }
    

    2、添加返回(响应)类

    public class ApiTools
    {
    	private string msgModel = "{{\"code\":{0},\"message\":\"{1}\",\"result\":{2}}}";
        public ApiTools()
        {       
        }
        public HttpResponseMessage MsgFormat(ResponseCode code, string explanation, string result)
        {
            string r = @"^(\-|\+)?\d+(\.\d+)?$";
            string json = string.Empty;
            if (Regex.IsMatch(result, r) || result.ToLower() == "true" || result.ToLower() == "false" || result == "[]" || result.Contains('{'))
            {
                json = string.Format(msgModel, (int)code, explanation, result);
            }
            else
            {
                if (result.Contains('"'))
                {
                    json = string.Format(msgModel, (int)code, explanation, result);
                }
                else
                {
                    json = string.Format(msgModel, (int)code, explanation, "\"" + result + "\"");
                }
            }
            return new HttpResponseMessage { Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json") };
        }
    }
    

    ResponseCode:

    public enum ResponseCode
    {
        操作失败 = 00000,
        成功 = 10200,
    }
    

    四、调用Web API接口

    1、给大家推荐一款比较好用的接口测试软件:
    https://www.getpostman.com
    这里写图片描述

    2、如果想测试上面写的post方法,启动Web Api项目后,在postman地址栏输入:http://localhost:26753/ActionApi/UserInfo/CheckUserName,添加参数 userName=张三
    结果如下:
    这里写图片描述

    还记得我们之前自定义的路由信息吗

    config.Routes.MapHttpRoute(
        name: "ActionApi",
        routeTemplate: "actionapi/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
    

    地址栏中的UserInfo 对应路由配置**{controller}参数
    CheckUserName 对应路由配置
    {action}参数
    userName=张三 对应 路由配置
    {id}**参数

    展开全文
  • Web API学习基础一

    千次阅读 2015-06-24 21:33:01
    开发环境VS2012、.NET 4.5 创建项目VS2012->文件->...在App_Start中,RouteConfig.cs文件配置MVC的路由规则,WebApiConfig.cs配置WebApi路由规则 在Controllers文件夹中编写控制器,可以编写MVC控制器也可以编写W
    1. 开发环境

      VS2012、.NET 4.5

    2. 创建项目

      VS2012->文件->新建->项目,选择ASP.NET MVC 4Web应用程序
      这里写图片描述

    3. 选择Web API项目,并使用Razor引擎

      这里写图片描述

    4. 目录结构

      这里写图片描述

    在App_Start中,RouteConfig.cs文件配置MVC的路由规则,WebApiConfig.cs配置WebApi的路由规则
    在Controllers文件夹中编写控制器,可以编写MVC控制器也可以编写WebAPI的控制,继承的类不一样

    1. Web API路由
     config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    路由决定了URL的格式。默认路由的URL格式为http://localhost/api/Student/1, 表示访问Student控制器,并传递id  
    

    =1

    6.访问规则
    Get方式:查询,无负做用,不管执行多少次都不会改变系统的状态
    Put方式:修改,执行一次或多次,对系统状态的改变是一样的
    Post方式:新增
    Delete方式:删除,执行一次或多次,对系统状态的改变是一样的

    通过Get方式访问,会查找以Get开头的所有Action,并匹配对应的参数,如果查找到两个方法,则会报错。所以Get开头的Action,必须参数不一样
    Put、Post、Delete也是一样
    示例:

     // GET api/values
            public IEnumerable<string> Get()
            {
                return new string[] { "value1", "value2" };
            }
    
            // GET api/values/5
            public string Get(int id)
            {
                return "value";
            }

    可以通过如下方式访问不带参数的Get方法:
    GET http://localhost/Student/

    也可以通过给Action加上Attribute改变访问方式

     // GET api/values/5
            [HttpPut]
            public string Get(int id)
            {
                return "value";
            }

    添加HttpPut之后就只能通过Put方式访问了

    1. 如何通过Action名称访问对应Action
      可以在WebApiConfi.cs文件中增加路由规则
    config.Routes.MapHttpRoute(
                   name: "DefaultApi",
                   routeTemplate: "api/{controller}/{action}/{id}",
                   defaults: new { id = RouteParameter.Optional }
               );

    这样就可以通过action名称访问对应的action
    如果Action不是以Get、Post等方式开头,则必须添加HttpGet等Attribute。否则会出现访问错误。

    展开全文
  • 备注:如果你对ASP.NET MVC很熟悉,你会发现Web API路由和MVC路由非常相似。主要区别是Web API使用HTTP方法来选择动作(action),而不是URI路径。你也可以在Web API中使用MVC风格的路由。这篇文章需要ASP.NET MVC...

    这篇文章描述了ASP.NET Web API如何将HTTP请求发送(路由)到控制器。

    备注:如果你对ASP.NET MVC很熟悉,你会发现Web API路由和MVC路由非常相似。主要区别是Web API使用HTTP方法来选择动作(action),而不是URI路径。你也可以在Web API中使用MVC风格的路由。这篇文章不需要ASP.NET MVC的任何知识。

    路由表

    在ASP.NET Web API中,控制器是一个用于处理HTTP请求的类。控制器中的公共方法被称为动作方法或简单动作。当Web API框架收到请求时,它会将该请求路由到相应的动作中。

    为了确定哪个动作该被执行,框架就会使用本节将讲解的路由表。Visual Studio的Web API项目模板就创建了一个默认的路由表:

    routes.MapHttpRoute(
        name: "API Default",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
    

    这个路由被定义在App_Start目录下的WepApiConfig.cs文件中。

    这里写图片描述

    路由表中的每条记录都包含了一个路由模板。Web API的默认路由模板是“api/{controller}/{id}”。在这个模板中,”api”是一个字面路径字段,而{controller}和{id}都是占位符变量。

    当Web API框架收到了HTTP请求时,它将会尽力匹配URI到路由表中的路由模板的其中一个。如果没有路由被匹配到,客户端就会收到404错误。例如,以下URI会匹配到默认路由:

    1. /api/contacts
    2. /api/contacts/1
    3. /api/products/gizmo1

    然而,以下URI不会匹配到,因为它缺乏“api”字段。

    /contacts/1

    备注:在路由中使用“api”的原因是为了避免和ASP.NET MVC的路由冲突。也就是说,你可以使用”/contacts”匹配到MVC的路由,使用“api/contacts”匹配到Web API的路由。当然了,如果你不喜欢这种约定,你也可以修改默认路由表。

    一旦某个路由匹配到了,Web API就会选择相应的控制器及动作:

    1. 为了找到控制器,Web API将“Controller”添加到{controller}变量上。
    2. 为了找到动作,Web API会遍历HTTP方法,然后查找一个其名字以HTTP方法的名字开头的动作。例如,有一个GET请求,Web API会查找以“Get….”开头的动作,比如”GetContact”或”GetAllContacts”。这种方式仅仅适用于GET、POST、PUT和DELETE方法。你可以通过在你的控制器中使用属性来启用其他HTTP方法。将晚些看到一个示例(超链接到本章的第三节……
    3. 路由模板的其他占位符变量,比如{id},会被映射到动作的参数。

    让我们来看一个示例。假定你定义了如下的控制器:

    public class ProductsController : ApiController
    {
        public void GetAllProducts() { }
        public IEnumerable<Product> GetProductById(int id) { }
        public HttpResponseMessage DeleteProduct(int id){ }
    }
    

    这里是一些可能的HTTP请求,以及相应的得到执行的动作:

    HTTP Method URI Path Action Parameter
    GET api/products GetAllProducts (none)
    GET api/products/4 GetProductById 4
    DELETE api/products/4 DeleteProduct 4
    POST api/products (no match)

    注意URI的{id}字段,如果存在,它会被映射到动作的id参数中。在本例,控制器定义了两个GET方法,其中一个包含id参数,而另一个不包含id参数。

    同样的,注意到POST请求会失败,因为控制器中并没有定义”POST…”方法。

    路由偏差(Routing Variations)

    前一节描述了ASP.NET Web API的基本路由机制。本节将开始描述一些变化。

    HTTP方法

    除了使用这些HTTP方法的命名约定,你也可以通过用HttpGet、HttpPut、HttpPost或HttpDelete属性来赋予这些动作来具体地为每个动作设定HTTP方法。

    在下面这个例子中,FindProduct方法被映射到GET请求:

    public class ProductsController : ApiController
    {
        [HttpGet]
        public Product FindProduct(id) {}
    }
    

    为了让一个动作支持多个HTTP方法,或支持除GET、PUT、POST和DELETE之外的HTTP方法,你可以使用AcceptVerbs属性,它以一个HTTP方法列表为参数。

    public class ProductsController : ApiController
    {
        [AcceptVerbs("GET", "HEAD")]
        public Product FindProduct(id) { }
    
        // WebDAV method
        [AcceptVerbs("MKCOL")]
        public void MakeCollection() { }
    }
    

    通过动作名进行路由

    有了默认的路由模板,Web API使用HTTP方法来选择动作。然而,你也可以创建一个将动作名包含在URI中的路由表。

    routes.MapHttpRoute(
        name: "ActionApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
    

    在这个路由模板中,{action}参数在控制器中命名了一个动作方法。在这种风格的路由中,应使用属性来指定允许的HTTP方法。例如,假定你的控制器有了以下方法:

    public class ProductsController : ApiController
    {
        [HttpGet]
        public string Details(int id);
    }
    

    在这种情况下,对于“api/products/details/1”的GET请求被被映射到Details方法。这种风格的路由和ASP.NET MVC很接近,并且可能适合于RPC风格的API。

    你可以通过ActionName属性来重写动作名。在接下来的例子中,存在两个都映射到”api/products/thumbnail/id”的动作。其中一个支持GET,另一个支持POST:

    public class ProductsController : ApiController
    {
        [HttpGet]
        [ActionName("Thumbnail")]
        public HttpResponseMessage GetThumbnailImage(int id);
    
        [HttpPost]
        [ActionName("Thumbnail")]
        public void AddThumbnailImage(int id);
    }
    

    无动作(Non-Actions)

    为了阻止一个方法被当作动作来执行,可以使用NonAction属性。这会框架指明该方法并非一个动作,即使是它可能匹配到路由规则。

    // Not an action method.
    [NonAction]  
    public string GetPrivateData() { ... }
    
    展开全文
  • SpringBoot的URL路由

    千次阅读 2019-01-19 00:51:37
    Restful API GET http://localhost:8080/api/v1/users 获取用户列表 POST http://localhost:8080/api/v1/users 新增一个用户 GET http://localhost:8080/api/v1/users/{id} 获取某个用户信息 PUT ...
  • 微软的WebAPI默认实现逻辑 默认实现中支持同名Controller,否则在访问时会报HttpError,在网上找到了各种路由自实现,如 给ASP.net Web API的Controller分类 搭建MVC及WebAPI项目框架时碰到的问题集合 在上述地址...
  • ASP.NET WebApi 路由配置

    千次阅读 2017-06-19 15:40:20
    ASP.NET Web API路由是整个API的入口。我们访问某个资源就是通过路由映射找到对应资源的URL。通过URL来获取资源的。 对于ASP.NET Web API内部实现来讲,我们的请求最终将定位到一个具体的Action上。所以说,ASP...
  • 修改 mvc webapi 默认返回 json 格式

    万次阅读 2015-09-29 16:45:04
    修改 mvc webapi 默认返回 json 格式
  • 备注:想要了解关于路由的高层次概述,请查看Routing in ASP.NET Web API。这篇文章侧重于路由过程的细节。如果你创建了一个Web API项目并且发现一些请求并没有按你预期得到相应的路由,希望这篇文章有所帮助。路由...
  • .NET MVC/.NET COER 下WebApi基本使用如下 //[RoutePrefix("api/Values/")]//action就可以去掉这一节;如果某个方法又不要了,可以在路由前面加个~ [Route("~api/Values/{id:int}")] public class ValuesController ...
  • WebApi特性路由路由前缀

    千次阅读 2017-07-02 23:01:00
    WebApi2默认的路由规则我们称作基于约定路由,很多时候我们使用RESTful风格的URI.简单的路由是没问题的,如 api/Products/{id},但有些事很难处理的,如资源之间存在嵌套关系:客户包含订单,书有作者属性等等。对于...
  • C# WebAPI创建及具体实现

    千次阅读 2018-11-22 22:41:47
    Web API 其实就是应用程序编程接口,在实际的生活中,我们使用的软件有很多都是从API中获取的数据,比如:天气预报,微信支付等都是使用的接口,这样我们在编程过程中就可以使用别人已经写好的接口,可以省很多时间...
  • Asp.net WebAPI 构建后台数据接口

    千次阅读 2017-07-10 15:33:50
    选择WebApi,并使用空模板(这里想要一些其他的mvc的东西)3.新建一个model4.写几个属性using System; using System.Collections.Generic; using System.Linq; using System.Web;namespace APITest.Models { ...
  • ASP.NET Web API 中的路由以及Action的选择 原文更新日期:2017.11.28 导航页面 http://blog.csdn.net/wf824284257/article/details/79475115 上一步 ASP.NET Web API 中的路由 ...
  • 控制器中使用 public class IOCController : ApiController { private IUserService _UserService = null; public IOCController(IUserService userService) { this._UserService = userService; } public ...
  • (精华)2020年9月22日 微服务 WebAPI详解

    万次阅读 2020-09-22 22:59:20
    if (!(Test-Path -Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force }
  • 前言 刚开始创建MVC与Web API的混合项目时,碰到好多...问题大概有以下几点: 1、项目层的文件夹结构 2、解决MVC的Controller和Web API的Controller类名能相同的问题 3、给MVC不同命名空间的Area的注册不同的路由 4
  • webapi Route 特性

    千次阅读 2017-04-01 10:17:58
    ASP.NET Web API路由,简单来说,就是把客户端请求映射到对应的Action上的过程。在"ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置"一文中,体验了通过模版、惯例、HTTP方法来设置路由,这种做法的好处是...
  • 1、...当传入的 c 值为 “site”, a 值为 “entry”时则是一个模块路由,m则表示模块对应的名称,该页面对应的视图和控制器文件都在 addons/ewei_shopv2目录下 do=web表示模...
  • Spring Cloud Gateway基于服务发现的默认路由规则

    万次阅读 热门讨论 2018-06-21 18:33:28
    1.Spring Gateway概述1.1 什么是Spring Cloud Gateway Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等... Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式...
1 2 3 4 5 ... 20
收藏数 16,122
精华内容 6,448
关键字:

webapi路由规则 不使用id