关于.net:如何在-ASPNET-Core-中使用-Route-特性

51次阅读

共计 3615 个字符,预计需要花费 10 分钟才能阅读完成。

ASP.NET Core 中的 Route 中间件的职责在于将 request 匹配到各自 Route 处理程序上,Route 分两种:基于约定 根本个性 模式。

基于约定 模式的 Route 采纳集中化的形式,而 基于个性 的形式容许你在 Action 或者 Controller 上独自定义,到底采纳哪一种能够基于你本人的利用场景,本篇就来探讨如何应用 基于个性 模式。

创立 Controller 类

创立一个 DefaultController 类,新增如下代码。


    public class DefaultController : Controller
    {[Route("")]
        [Route("Default")]
        [Route("Default/Index")]
        public ActionResult Index()
        {return new EmptyResult();
        }
        [Route("Default/GetRecordsById/{id}")]
        public ActionResult GetRecordsById(int id)
        {
            string str = string.Format
            ("The id passed as parameter is: {0}", id);
            return Ok(str);
        }
    }

Controller 级别定义 Route 个性

Route 个性可用于 Controller 和 Action 级别,值得注意的是,如果应到到前者,那么 Controller 下的所有 Action 都受这个 Route 管控。

如果你仔细观察下面的 DefaultController 类代码,你会发现两个 Action 办法的 Route 门路都有 Default 前缀,这就不优雅了,优化形式就是把 Route 门路中的 Default 提取到 Controller 级别,代码如下:


[Route("Default")]   
public class DefaultController : Controller
{[Route("")]
  [Route("Index")]
  public ActionResult Index()
  {return new EmptyResult();
   }
  [HttpGet]
  [Route("GetRecordsById/{id}")]
  public ActionResult GetRecordsById(int id)
  {string str = string.Format("The id passed as parameter is: {0}", id);
      return Ok(str);
   }
}

能够看出当 Controller 和 Action 级别都被 Route 打上标记之后,Asp.Net Core 中的 Route 引擎会主动将两者拼接起来,当然更简略粗犷的做法就是在 Controller 上应用 RoutePrefix 个性,如下代码所示:


[RoutePrefix("services")]
public class HomeController : Controller
{//Action methods}

Action 级别定义 Route 个性

参考方才的 DefaultController 类,我在 Index 办法下面定义了三个 Route 个性,这就意味着上面三种 Route 都能够拜访到 Index() 办法,如下代码所示:


http://localhost:11277
http://localhost:11277/home
http://localhost:11277/home/index

经常在 基于约定 模式的 Route 中,它的 Route template 会有一些对参数的约定,比方上面的代码:


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });

同样 基于个性 模式的 Route 也是能够应用参数模式的,比方文章之前的 DefaultController.GetRecordsById 就是的,值得注意的是模板中的 {id} 示意可接管任何参数,如 string,int 等等,如果你想限定为 int 的话,也是能够实现的。

应用 Route 束缚

Route 束缚 就是 Controller 前的一个防火墙,他会踢掉一些不合标准的 Action 申请,比如说:你要求某个 Action 接管的参数必须是 int,那在 Route 模板中定义的语法格局肯定是这样的 {parameter:constraint},如下代码所示:


[Route("Default/GetRecordsById/{id:int}")]
public ActionResult GetRecordsById(int id)
{string str = string.Format("The id passed as parameter is: {0}", id);
  return Ok(str);
}

在 Route 中应用可选参数

你也能够在 Route Template 上指定可选参数,意味着这个参数可传可不传,格局如下:


[Route("Sales/GetSalesByRegionId/{id?}")]

有一点十分重要,当你应用了 Route 个性 之后,其实 Controller 或者 Action 的名字就不再重要了,因为 Route 解决引擎 曾经不再将其作为参考选项,上面的代码片段展现了如何在 Action 办法上变更 Route template 格局。


[Route("Home/GetRecordsById/{id:int}")]
public ActionResult GetRecordsById(int id)
{string str = string.Format("The id passed as parameter is: {0}", id);
   return Ok(str);
}

接下来能够间接应用如下地址拜访 GetRecordsById 办法。


http://localhost:11277/home/GetRecordsById/1

对 Action 中的参数应用多个束缚

实在场景中你不仅要求 id 必须是整数,还要求必须有肯定意义,比如说最小值为 1,对这种有 多重束缚 的需要如何去实现呢?请看上面代码。


[Route("Default/GetRecordsById/{id:int:min(1)}")]
public ActionResult GetRecordsById(int id)
{string str = string.Format("The id passed as parameter is: {0}", id);
    return Ok(str);
}

常应用的 Route 束缚

  • int 限定为 int 类型
  • max/min 限定 int 的最大数和最小数
  • minlength 限定 string 的最小长度
  • regex 限定合乎的正则

创立自定义的 Route 束缚

如果下面的一些束缚不满足你的要求,你齐全能够为你的场景深度定制,做法就是应用 IRouteConstraint 接口并实现它的 Match 办法即可,如下代码所示:


    public class CustomRouteConstraint : IRouteConstraint
    {
        public bool Match(HttpContext httpContext, IRouter route,
        string routeKey,
        RouteValueDictionary values, RouteDirection routeDirection)
        {throw new NotImplementedException();
        }
    }

在 Controller 上应用 token 占位符

所谓的 token 占位符 就是具备一些特定含意的占位符号,比如说:[action], [area] 和 [controller],别离示意用你实在的 Controller 和 Action 去替换,上面的代码展现了如何应用这种模式去实现。


[Route("[controller]/[action]")]
public class HomeController : Controller
{
   private readonly ILogger<HomeController> _logger;
   public HomeController(ILogger<HomeController> logger)
   {_logger = logger;}
   public IActionResult Index()
   {return View();
   }
   //Other action methods
}

整体来看,基于个性 的 Route 给了你更多的操控权限,灵便的 Route Template 配置实现了 Controller 和 Action 的解耦,当然这里也不是说 基于约定 的 Route 不好,毕竟人家是 Global 级别的,实在场景下两者更多的是混着用。

译文链接:https://www.infoworld.com/art…

更多高质量干货:参见我的 GitHub: csharptranslate

正文完
 0