繁体   English   中英

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

[英]Compose route template in AspNetCore.Mvc controller

我的控制器:

[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}/");
   });

仅当我输入url“ 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'的替换值。 可用令牌:“操作,控制器”。 要在路线中或约束内将'['或']'用作文字字符串,请改用'[['或']]'。

属性路由解决方案

无需在Startup中使用MapRoute ,而是创建自定义基类-

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

现在,从该基类而不是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] ,因此保留了其提供的所有功能

旧解决方案

根据您的要求,如果您只是从Controller中删除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而不是Map route。
  • 同样,属性路由具有其自身的优点 正如我之前提到的“根据您的要求”,如果您不使用“属性路由”的任何功能,则可以使用此方法。

对于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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM