在AspNetCore.Mvc控制器中撰写路由模板

时间:2019-07-17 09:16:59

标签: c# asp.net-core

我的控制器:

[Route("Categories")]
[ApiController]
public class CategoriesController : ControllerBase
{
    [HttpGet]
    [Route("My")]
    public string[] My()
    {
        return new[]
        {
            "Is the Microwave working?",
            "Where can i pick the washing machine from?",
        };
    }
}

我的startup.cs Configure():

app.UseMvc(routes =>
   {
       routes.MapRoute(name: "api", template: "api/v1/{controller}/{action}/");
   });

仅当我点击网址“ https://localhost:44325/categories/my”时该方法才有效

我需要它具有“ https://localhost:44325/api/v1/categories/my”。

我应该设定什么不同?

我尝试在控制器上使用类似[Route("[api]/Categories")]属性的方法来组成所需的路线,但是它不起作用...

我知道了

  

属性路由信息发生以下错误:

     

错误1:采取措施:   'historyAccounts.WebApi.Controllers.CategoriesController.My   (historyAccounts.WebApi)'错误:处理模板时   '[api] / Categories / My',令牌'api'的替换值可以   找不到。可用令牌:“操作,控制器”。使用“ [”或   ']'作为路径中或约束内的文字字符串,请使用'[['或   ']]'。

3 个答案:

答案 0 :(得分:2)

具有属性路由的解决方案

MapRoute中使用Startup来创建自定义基类-

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

现在从该基类而不是ControllerBase-

派生所有控制器。
public class CategoriesController : MyControllerBase
{
    [HttpGet]
    public string[] My()
    {
        return new[]
        {
            "Is the Microwave working?????",
            "Where can i pick the washing machine from?",
        };
    }
}

这样可以满足您的所有要求-

  1. 您的版本信息集中在MyControllerBase
  2. 保留[ApiController],并保留其提供的所有功能

旧解决方案

根据您的要求,如果您仅从控制器中删除Route属性,它就可以按照您想要的方式工作-

public class CategoriesController : ControllerBase
{
   [HttpGet]
   public string[] My()
   {
       return new[]
       {
           "Is the Microwave working?",
           "Where can i pick the washing machine from?",
       };
   }
}

保持您的路线图不变-

app.UseMvc(routes =>
{
   routes.MapRoute(name: "api", template: "api/v1/{controller}/{action}/");
});
  • 如果您注意到,除了删除Route属性外,我还从类中删除了[ApiController]属性。此属性强制用户使用Route而不是地图路由。
  • 此外,属性路由具有自己的benefits。正如我之前提到的“根据您的要求”,如果您不使用“属性路由”的任何功能,则可以使用此方法。

答案 1 :(得分:1)

对于MVC会话路由和属性路由,属性路由将覆盖会话路由。

对于@Gaurav Mathur的解决方案,所有控制器都需要在请求网址后附加api/v1

根据您的情况,如果要启用api版本,则可以尝试使用Web api版本功能,而不是在mvc会话中配置路由。

  1. 安装软件包Microsoft.AspNetCore.Mvc.Versioning
  2. Startup.cs中配置

    services.AddApiVersioning(opt => {
        opt.DefaultApiVersion = new ApiVersion(1,0); //this is your version v1
    });
    
  3. ApiController

    [Route("api/v{version:apiVersion}/[controller]/[action]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        [HttpGet]
        public IActionResult Hello()
        {
            return Ok("Test");
        }
    }
    
  4. 请求网址:https://localhost:44369/api/v1/values/hello

答案 2 :(得分:0)

我已经接受了以前的答案,但是另一种可能的方法是全局常量(即在启动时声明):

public const string BaseUrl = "/api/v1/"; 

[Route(Startup.BaseUrl + "[controller]")]
[ApiController]
public class CategoriesController : ControllerBase