.Net 6 中所有 ApiController 的全局路由

Global route for all ApiControllers in .Net 6

在我所有的项目中,我都将这段代码放在我的控制器顶部:

[Route("api/[controller]/[action]")]
[ApiController]
public class ValuesController : ControllerBase
{
    [HttpGet]
    public IActionResult GetTest1()
    {
        return Ok();
    }
    [HttpGet]
    public IActionResult GetTest2()
    {
        return Ok();
    }
    [HttpPost]
    public IActionResult PostTest1(string Request)
    {
        return Ok("value was " + Request);
    }
}

所以我可以使用动作名称调用我的 API,而无需指定每个动作路由,如下图所示:

这项工作很好,但我需要将这条路线放在我项目中所有 ApiControllers 的顶部,当我决定将我的所有路线更改为新路线时,我需要替换我的所有 RouteAttributes项目.

我在寻找全局解决方案,例如我的 program.cs 文件中的类似内容:

app.MapControllerRoute(
    name: "default",
    pattern: "api/{controller}/{action}");

问题是当我从我的 API 中删除 RouteAttribute 时我无法使这段代码工作。

刚刚在 Global route Prefix 上学习了这个简单的教程 在将全局路由前缀添加到 program.cs 文件后,您还必须删除控制器顶部的路由前缀。

我的招摇:

我的progam.cs

 builder.Services.AddMvc(opt =>
 {
     opt.UseCentralRoutePrefix(new RouteAttribute("core/v1/[controller]/[action]"));
 }

).AddControllersAsServices().AddNewtonsoftJson();

我为此搜索了几个小时,毕竟我没有找到任何简单的解决方案来为 API 创建良好、简单、快速的全局路由,然后我自己尝试了。

解决方案 1: 你可以为你的 API 创建一个基础 class 并将你的路由放在那个文件中,然后你只在你的所有 API 中从那个 class 继承。

APIBase.cs 文件:

[ApiController]
[Route("api/[controller]/[action]")]
public class APIBase: ControllerBase
{
}

下一步:如果您需要在 URL 中包含 id(或任何其他参数),那么您应该仅为该方法添加 RouteAttribute。

ValuesController.cs 文件:

public class ValuesController : APIBase
{
    [HttpGet]
    public IActionResult GetTest1()
    {
        return Ok();
    }
    [HttpGet]
    [Route("{id?}")]
    public IActionResult GetTest2(int id)
    {
        return Ok("value was " + id);
    }
    [HttpPost]
    public IActionResult PostTest1(string Request)
    {
        return Ok("value was " + Request);
    }
}

编辑:

解决方案 2:您可以在您的项目中创建一个字符串常量并在所有 API 中使用它(@Serge 建议)

HelperStatic.cs 文件:

public static class HelperStatic
{
    public const string BaseAPIRoute = "api/[controller]/[action]";
}

ValuesController.cs 文件:

[ApiController]
[Route(HelperStatic.BaseAPIRoute)]
public class ValuesController : ControllerBase
{
    [HttpGet]
    public IActionResult GetTest1()
    {
        return Ok();
    }
    [HttpGet]
    [Route("{id?}")]
    public IActionResult GetTest2(int id)
    {
        return Ok("value was " + id);
    }
    [HttpPost]
    public IActionResult PostTest1(string Request)
    {
        return Ok("value was " + Request);
    }
}

你的招摇会是这样的(在两种解决方案上):