《Asp.Net Web Api 》-----路由机制
https://blog.csdn.net/zhoukun1008/article/details/52704651
前言
上一篇文章小编大体说了一下WebApi的简单应用程序,今天小编跟大家来讨论一下WebApi中的路由。如果你熟悉ASP.NET MVC,Web API路由与MVC路由十分类似。主要差别是Web API使用HTTP方法而不是URI路径来选择动作。你也可以在Web API中使用MVC风格的路由。
1、路由表
在ASP.NET Web API中,一个控制器是处理HTTP请求的一个类。控制器的public方法称为动作方法(action methods)或简称为动作(action)。当Web API框架接收到一个请求时,它将这个请求路由到一个动作。
为了确定调用哪一个动作,框架使用了一个路由表(routing table)。Visual Studio中Web API的项目模板会创建一个默认路由,这条路由是在WebApiConfig.cs文件中定义的,该文件位于App_Start目录。
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.EnableSystemDiagnosticsTracing();
}
路由表中的每一个条目都包含一个路由模板(route template)。Web API的默认路由模板是“api/{controller}/{id}”。在这个模板中,“api”是一个文字式路径片段,而{controller}和{id}则是占位符变量。
当Web API框架接收一个HTTP请求时,它会试图根据路由表中的一个路由模板来匹配其URI。如果无路由匹配,客户端会接收到一个404(未找到)错误。例如,以下URI与这个默认路由的匹配:
- /api/contacts
- /api/contacts/1
- /api/products/gizmo1
在路由中使用“api”的原因是为了避免与ASP.NET MVC的路由冲突。通过这种方式,可以用“/contacts”进入一个MVC控制器,而“/api/contacts”进入一个Web API控制器。当然,如果你不喜欢这种约定,可以修改这个默认路由表。
一旦找到了匹配路由,Web API便会选择相应的控制和动作:为了找到控制器,Web API会把“控制器”加到{controller}变量的值(意即,把URI中的“控制器”作为{controller}变量的值)。为了找到动作,Web API会考查HTTP方法,然后寻找一个名称以HTTP方法名开头的动作。例如,对于一个GET请求,Web API会查找一个以“Get…”开头的动作,如“GetProduct”或“GetAllProduct”等。这种约定仅运用于GET、POST、PUT和DELETE方法。通过把注解属性运用于控制器,你可以启用其它HTTP方法。后面会看到一个例子。路由模板中的其它占位变量,如{id},被映射成动作参数。
2、Demo
public class WebApiController : ApiController
{
/// <summary>
/// 定义一个产品数据
/// </summary>
Product[] products = new Product[]
{
new Product { Id = 1, Name = "农夫山泉", Category = "water", Price = 2 },
new Product { Id = 2, Name = "钢笔", Category = "study", Price = 3.75M },
new Product { Id = 3, Name = "烤肠", Category = "food", Price = 1 },
new Product { Id = 4, Name = "崂山矿泉水", Category = "water", Price = 2 },
new Product { Id = 5, Name = "铅笔", Category = "study", Price = 3.75M },
new Product { Id = 6, Name = "烤羊肉串", Category = "food", Price = 1 }
};
/// <summary>
/// 得到所有的产品
/// </summary>
/// <returns></returns>
public IEnumerable<Product> GetAllProducts()
{
return products;
}
/// <summary>
/// 根据id查询产品
/// </summary>
/// <param name="id">产品id</param>
/// <returns></returns>
public Product GetProductById(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
/// <summary>
/// 根据产品种类查询产品
/// </summary>
/// <param name="category">产品种类</param>
/// <returns></returns>
public IEnumerable<Product> GetProductsByCategory(string category)
{
return products.Where(
(p) => string.Equals(p.Category, category,
StringComparison.OrdinalIgnoreCase));
}
/// <summary>
/// 根据id删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public List<int> DeleteProductById(int id)
{
List<int> p = new List<int>();
for (int i = 0; i < 6; i++)
p.Add(i);
p.Remove(id);
if (p == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return p;
}
/// <summary>
/// 根据id增加
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public List<int> PostProductById(int id)
{
List<int> p = new List<int>();
for (int i = 0; i < id; i++)
p.Add(i);
if (p == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return p;
}
}
其它的几个测试方法我省略。现在我们更改一下路由表,使其根据Controller 来确定访问哪个类,根据Action来确定访问哪个方法。
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.EnableSystemDiagnosticsTracing();
}
对应的方法:
public class RouteDemoController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = 1, Name = "农夫山泉", Category = "water", Price = 2 },
new Product { Id = 2, Name = "钢笔", Category = "study", Price = 3.75M },
new Product { Id = 3, Name = "烤肠", Category = "food", Price = 1 },
new Product { Id = 4, Name = "崂山矿泉水", Category = "water", Price = 2 },
new Product { Id = 5, Name = "铅笔", Category = "study", Price = 3.75M },
new Product { Id = 6, Name = "烤羊肉串", Category = "food", Price = 1 }
};
/// <summary>
/// 查询所有商品
/// </summary>
/// <returns></returns>
[HttpGet]
public IEnumerable<Product> QueryAllProducts()
{
return products;
}
/// <summary>
/// 根据id查询商品
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public Product QueryProductById(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
/// <summary>
/// 根据种类查询商品
/// </summary>
/// <param name="category"></param>
/// <returns></returns>
[HttpGet]
public IEnumerable<Product> QueryProductsByCategory(string category)
{
return products.Where(
(p) => string.Equals(p.Category, category,
StringComparison.OrdinalIgnoreCase));
}
/// <summary>
/// 此动作不让请求
/// </summary>
[NonAction]
public void PrivateData()
{
}
}
测试效果如下
这就是更改过后的路由,有时候,我们还可以使用注解属性来代替Action的使用
[HttpGet]
[ActionName("Test")]
public Product findProductById(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return product;
}
测试结果如下
3、小结
这就是小编了解到的WebApi的路由,其实WebApi和Mvc方法中的区别是,MVC中返回的是视图的名字,而WebApi是返回的是数据。WebApi与WCF相比,WebApi比WCF重量级要小,小编所在的项目组用的就是WebApi,我们将css、HTML、AngularJS,打包成apk后,让用户按上,我们可以直接在apk中调用WebApi的服务。好了,小编总结到这吧。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)