asp.net mvc 增加WebApi
发布日期:2021-06-29 17:05:40 浏览次数:2 分类:技术文章

本文共 12437 字,大约阅读时间需要 41 分钟。

可能你还需要

c# asp.net mvc API接口安全过滤,api域名过滤,api域名+端口过滤

第一种

新建项目的时候可以直接勾选

勾选,“确定”后你会发现,项目多了这些文件

一、App_Start文件夹多了WebApiConfig.cs文件

using System;using System.Collections.Generic;using System.Linq;using System.Web.Http;namespace HaoSiJiaWeb{    public static class WebApiConfig    {        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 }            );          }    }}

 

 config.MapHttpAttributeRoutes();

 

这行代码的意思是开启的特性路由

之前写MVC的时候介绍过特性路由,感兴趣的可以点击下面链接进行查看

 

二、Global.asax多了一行代码

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Http;using System.Web.Mvc;using System.Web.Optimization;using System.Web.Routing;namespace HaoSiJiaWeb{    public class MvcApplication : System.Web.HttpApplication    {        protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            GlobalConfiguration.Configure(WebApiConfig.Register);            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);            RouteConfig.RegisterRoutes(RouteTable.Routes);            BundleConfig.RegisterBundles(BundleTable.Bundles);        }    }}
GlobalConfiguration.Configure(WebApiConfig.Register);//必须放第二行

 第二种

如果你想在你的现有MVC项目增加WebApi可以根据这个格式(步骤)加进去就行了

 

增加WebApi控制器

第一步:新建文件夹

在网站根目录新建文件夹“API”

第二步:增加控制器文件

在“API”文件夹右键》添加》Web API 控制器类

输入名称“TestController”

会生成下面代码

using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Http;using System.Web.Http;namespace HaoSiJiaWeb.Api{    public class TestController : ApiController    {        // GET api/
public IEnumerable
Get() { return new string[] { "value1", "value2" }; } // GET api/
/5 public string Get(int id) { return "value"; } // POST api/
public void Post([FromBody]string value) { } // PUT api/
/5 public void Put(int id, [FromBody]string value) { } // DELETE api/
/5 public void Delete(int id) { } }}

访问

访问地址:

目前访问的是第一个action的Get方法

注意:

直接输入地址访问的http请求都属于Get请求。

我们在提交表单的时候会有许多提交请求的方式,API会先判断你请求的方式,再根据你的请求方式去找到控制器里对应的action方法

在Web API里还有个特性,就是action方法开头如果是Get,他就会判定这个action是用来处理get请求的,

如果POST开头,他就会判定这个action是用来处理post请求的,

像put和delete也都类似

 

 

升级TestController 控制器文件

在文件里增加下面方法

public class TestController : ApiController    {              public string TestString()        {          return "TestString()";        }     }

我这里把所有生成的方法都删了,只留我自己写的 

第三步:在App_Start文件夹下新增路由文件WebApiConfig

public static class WebApiConfig    {        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 }          );            config.Routes.MapHttpRoute(            name: "DefaultApi2",            routeTemplate: "api/{controller}/{action}/{id}",            defaults: new { id = RouteParameter.Optional }            );        }    }

我这里在下面增加了一条新的路由状态

第四步:修改Global.asax 

在 Application_Start()方法新新增一行代码

GlobalConfiguration.Configure(WebApiConfig.Register);

完整代码

public class MvcApplication : System.Web.HttpApplication    {        protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            GlobalConfiguration.Configure(WebApiConfig.Register);//新增的,必须放第二行            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);            RouteConfig.RegisterRoutes(RouteTable.Routes);            BundleConfig.RegisterBundles(BundleTable.Bundles);        }    }

*需要引入

using WebAPINo.App_Start;using System.Web.Http;

其实,到这一步已经全部配置完成了,你可以试试看

访问

url:

理论上,我们这样访问是没有错的,可惜,只是理论上

运行报错

<Error>

<Message>请求的资源不支持 http 方法“GET”。</Message>

</Error>

根据,上面我们讲的

在Web API里还有个特性,就是action方法开头如果是Get,他就会判定这个action是用来处理get请求的,

如果POST开头,他就会判定这个action是用来处理post请求的,

像put和delete也都类似

我们把方法改成这样的

public string GetTestString(){          return "GetTestString()";}

在名字前面增加Get

访问url:

结果

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">GetTestString()</string>

已经访问成功了

 

那么,有没有另一种方法呢?

答案是“有”,在方法上面增加特性

[HttpGet]public string TestString(){  return "[HttpGet]TestString()";}

特性有:[HttpGet]、[HttpPost]、[HttpPut]、[HttpDelete] 你可以根据你的需求使用

访问URL:

结果

[HttpGet]TestString()

 


******************【以上API功能添加配置完成】******************

下面是延伸阅读


 

你还可以给方法匿名

[ActionName("TS")][HttpGet]public string TestString(){  return $@"[ActionName(TS)]+[HttpGet]TestString()";}

这样你就可以用TS来代替方法名了

访问URL:

结果

[ActionName(TS)]+[HttpGet]TestString()

还有一种就更神奇了,就是特性路由


 

Web API 特性路由

 

上面我们讲到过在App_Start文件夹下的WebApiConfig.cs文件里面有这么一行代码

config.MapHttpAttributeRoutes();

这个就是开启特性路由的意思,系统默认开启

升级TestController控制器

[Route("api/Test/TestRoute")][HttpGet]public string TestRoute(){   return $@"使用特性路由+[HttpGet]TestRoute()";}

访问URL:

结果

使用特性路由+[HttpGet]TestRoute()

当然,依旧可以匿名

[Route("api/Test/TR")][HttpGet]public string TestRoute(){    return $@"使用特性路由---匿名+[HttpGet]TR/TestRoute()";}

访问URL:http://localhost:58088/api/Test/TR/

结果

使用特性路由---匿名+[HttpGet]TR/TestRoute()

是不是很简单  o(∩_∩)o 哈哈

使用带参数的特性路由

[Route("api/Test/TestRoute/{id}")][HttpGet]public string TestRoute(int id){    return $@"使用带参数的特性路由+[HttpGet]TestRoute(int id)传参为:{id}";}

访问URL:http://localhost:58088/api/Test/TestRoute/5

结果

使用带参数的特性路由+[HttpGet]TestRoute(int id)传参为:5

 

使用带参数类型约束的特性路由

[Route("api/Test/TestRoute/{id:int=5}")][HttpGet]public string TestRoute(int id){    return $@"使用带参数类型约束的特性路由+[HttpGet]TestRoute(int id)传参为:{id}";}

这里约束可变部分{id}的取值必须是int类型。并且默认值是5.

访问:

结果:

使用带参数类型约束的特性路由+[HttpGet]TestRoute(int id)传参为:5

访问:

结果:

使用带参数类型约束的特性路由+[HttpGet]TestRoute(int id)传参为:7

访问:

结果:

找不到与请求 URI“http://localhost:58088/api/Test/TestRoute/a”匹配的 HTTP 资源。
在控制器“Test”上找不到与名称“TestRoute”匹配的操作。

这里之所以会报错,是因为我们特性约束了id必须为int类型

使用多参数的特性路由

[Route("api/Test/TestRoute/{name}/{age:int=1}")][HttpGet]public string TestRoute(string name,int age){    return $@"使用多参数的特性路由+[HttpGet]TestRoute(string name,int id){name}的年龄是{age}岁";}

访问:

结果

使用多参数的特性路由+[HttpGet]TestRoute(string name,int id)Peter的年龄是25岁

访问:localhost:58088/api/Test/TestRoute/老吴/25

结果

使用多参数的特性路由+[HttpGet]TestRoute(string name,int id)老吴的年龄是25岁

TestController.cs完整代码

using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Http;using System.Web.Http;namespace HaoSiJiaWeb.Api{    public class TestController : ApiController    {        ///         /// 方法名字前面增加处理请求的类型        /// 访问url:http://localhost:58088/api/Test/TestString/        ///         //public string GetTestString()        //{        //  return "GetTestString()";        //}         ///         /// 方法上面增加特性说明[HttpGet]        /// 访问url:http://localhost:58088/api/Test/TestString/        ///         //[HttpGet]        // public string TestString()        //{        //  return "[HttpGet]TestString()";        //}         ///         /// 使用匿名特性[ActionName("TS")]        /// 访问url:http://localhost:58088/api/Test/TS/        ///         [ActionName("TS")]        [HttpGet]        public string TestString()        {            return $@"[ActionName(TS)]+[HttpGet]TestString()";        }        ///         /// 使用特性路由        /// 访问URL:http://localhost:58088/api/Test/TestRoute/        ///          //[Route("api/Test/TestRoute")]        //[HttpGet]        //public string TestRoute()        //{        //    return $@"使用特性路由+[HttpGet]TestRoute()";        //}        ///         /// 使用特性路由---匿名        /// 访问URL:http://localhost:58088/api/Test/TR/        ///          [Route("api/Test/TR")]        [HttpGet]        public string TestRoute()        {            return $@"使用特性路由---匿名+[HttpGet]TR/TestRoute()";        }        ///         /// 使用带参数的特性路由        /// 访问URL:http://localhost:58088/api/Test/TestRoute/5        ///          //[Route("api/Test/TestRoute/{id}")]        //[HttpGet]        //public string TestRoute(int id)        //{        //    return $@"使用带参数的特性路由+[HttpGet]TestRoute(int id)传参为:{id}";        //}        ///         /// 使用带参数类型约束的特性路由        /// 访问URL:http://localhost:58088/api/Test/TestRoute/5        ///          [Route("api/Test/TestRoute/{id:int=5}")]        [HttpGet]        public string TestRoute(int id)        {            return $@"使用带参数类型约束的特性路由+[HttpGet]TestRoute(int id)传参为:{id}";        }        ///         /// 使用多参数的特性路由        /// 访问URL:http://localhost:58088/api/Test/TestRoute/Peter/25        ///          [Route("api/Test/TestRoute/{name}/{age:int=1}")]        [HttpGet]        public string TestRoute(string name, int age)        {            return $@"使用多参数的特性路由+[HttpGet]TestRoute(string name,int id){name}的年龄是{age}岁";        }    }}

 

 


特性路由-进阶篇

在同一个控制器里,我们为了保证URL前面的路径一致,我们需要这样做

 

新建MoveRouteController.cs

我们新建一个MoveRouteController.cs的Web API控制器

在正式项目中,同一个控制器的所有的action的所有特性路由标识一个相同的前缀,这种做法并非必须,但这样能够增加url的可读性。一般的做法是在控制器上面使用特性[RoutePrefix]来标识。

完整代码:

using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Http;using System.Web.Http;namespace HaoSiJiaWeb.Api{    [RoutePrefix("api/MoveRoute")]    public class MoveRouteController : ApiController    {         ///         /// 使用带参数类型约束的特性路由        /// 访问URL:http://localhost:58088/api/MoveRoute/MRoute        ///          [HttpGet]        public string MRoute()        {            return $@" MRoute()";        }        ///         /// 使用带参数类型约束的特性路由        /// 访问URL:http://localhost:58088/api/MoveRoute/TestRoute        ///          [Route("TestRoute/{id:int=5}")]        [HttpGet]        public string TestRoute(int id)        {            return $@"使用带参数类型约束的特性路由+[HttpGet]TestRoute(int id)传参为:{id}";        }    }}

我们在控制器顶部用[RoutePrefix("")]约束好URL开头后,后面的[Route("")]直接写action名称即可,

请仔细看上面代码标注里的URL,你就会发现他的神奇


延伸阅读

WebApiConfig.cs的路由配置说明

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

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

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

分别来看看各个参数的作用:

  • name:"DefaultApi"→表示此路由的名称,这里只需要保证路由名称不重复就OK了。
  • routeTemplate: "api/{controller}/{id}"→表示路由的url规则,“api”是固定部分,主要用来标识当前请求的url是一个api服务的接口,区别MVC的路由,当然,这里并不是一定要写成“api”,如果你改成“apiserver”,那么你请求的url里面也需要写成“apiserver”;“{controller}”是控制器的占位符部分,在真实的url里面,该部分对应的是具体的控制器的名称,这个和MVC里面一致;“{id}”是参数的占位符部分,表示参数,一般这个参数都会在default里面设置可选。有了这个路由模板约束请求的url,比如:我们请求的url写成http://localhost:21528/Order,那么肯定是找不到对应的路由的,因为“api”这个参数必选。如果请求的url匹配不到对应的路由,则会向客户端返回一个404的状态码。
  • defaults: new { id = RouteParameter.Optional }→表示路由的默认值,比如上面的routeTemplate,{controller}和{id}部分都可以设置默认值,比如:defaults改成new { controller="Order", id = RouteParameter.Optional },那么我们请求http://localhost:21528/api这个url仍然能访问到GetAll()方法。
  • constraints→表示路由约束,一般是一个约束路由模板的正则表达式。比如:我们加入约束条件 constraints: new { id = @"\d+" } ,这就约束必须要匹配一到多个参数id,那么,我们在OrderController里面加入另一个方法
public class OrderController : ApiController    {        [HttpGet]        public object GetAll()        {            return "Success";        }        [HttpGet]        public object GetById(int id)        {            return "Success" + id ;        }    }

WebApiConfig.cs文件再增加一个路由

config.Routes.MapHttpRoute(           name: "DefaultApi3",            routeTemplate: "api2/{controller}/{id}",            defaults: new { id = RouteParameter.Optional },            constraints:new { id = @"\d+" }             );

我们加入约束条件 constraints: new { id = @"\d+" } ,这就约束必须要匹配一到多个参数id

我们通过来访问,得到结果:

 

 

我们再通过来访问,得到结果:

这个是很好理解的,id的值不匹配正则表达式。

而我们访问。结果:

竟然连GetAll()方法都找不到了。这是为什么呢?原来就是这个约束在作怪,正则\d+表示匹配一个或多个数字,所以如果请求的url里面没有传数字,则自动匹配不到。所以,如果需要匹配无参的方法,我们把约束改成这样: constraints: new { id = @"\d*" } ,这个表示匹配0个或多个数字,再来试试

config.Routes.MapHttpRoute(           name: "DefaultApi3",            routeTemplate: "api2/{controller}/{id}",            defaults: new { id = RouteParameter.Optional },            constraints:new { id = @"\d*" }             );

这样就OK了。

上述说了那么多都是约束id的,其实你也可以使用表达式去约束controller、action等等,但一般不常用,我们就不做过多讲解。


参考:

C#进阶系列——WebApi 路由机制剖析:你准备好了吗?

 

转载地址:https://cplvfx.blog.csdn.net/article/details/106493333 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:c# asp.net mvc提交json数据是空的
下一篇:MySQL数据库的安装总结

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月17日 12时03分33秒