繁体   English   中英

继承 .NET 核心中的路由属性 Web API

[英]Inheriting route attribute in .NET Core Web API

假设我将制作以下 REST API:

https://somedomain.com/api/Companies/{cid}

https://somedomain.com/api/Companies/{cid}/Employees/{eid}

https://somedomain.com/api/Companies/{cid}/Products/{pid}

在上述情况下,我需要路由( Route()属性)是可扩展的,以便可以形成路由层次结构。 我尝试了不同的方法,但它们似乎都不像样。 任何人都可以就如何实现routing inheritance给我建议...

    [Route("api/CompaniesController/{cid}")]
    [ApiController]
    public class CompaniesController : ControllerBase
    {
    }

    [Route("Employees/{eid}")]
    public class EmployeesController: CompaniesController 
    {
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
    }

    [Route("Products/{pid}")]
    public class ProductsController: CompaniesController 
    {
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
    }

您不应该为此使用不同的控制器,您应该在同一个 controller 中使用操作,因此这些操作可以“继承” controller 路由。

我将您的示例更改为:

[Route("api/Companies/{cid}")]
[ApiController]
public class CompaniesController : ControllerBase
{
}

[HttpGet]
[Route("Employees/{eid}")]
public IEnumerable<string> GetEmployees(string cid, string eid)
{
    return new string[] { "value1", "value2" };
}

[HttpGet]
[Route("Products/{pid}")]
public IEnumerable<string> GetCompanies(string cid, string pid)
{
    return new string[] { "value1", "value2" };
}

或者,如果您想保留完整路线作为示例,但想要单独的控制器(以避免单个 controller 具有数十个操作),您可以使用这样的单独控制器,只需在每个 controller 上添加您想要的完整路线:

[Route("api/Companies/{cid}")]
[ApiController]
public class CompaniesController : ControllerBase
{
}

[Route("api/Companies/{cid}/Employees/{eid}")]
public class EmployeesController: ControllerBase
{
    [HttpGet]
    public IEnumerable<string> Get(string cid, string eid)
    {
        return new string[] { "value1", "value2" };
    }
}

[Route("api/Companies/{cid}/Products/{pid}")]
public class ProductsController: ControllerBase 
{
    [HttpGet]
    public IEnumerable<string> Get(string cid, string pid)
    {
        return new string[] { "value1", "value2" };
    }
}

[Route("api/Companies/{cid}/Employee/{eid}/Privilege/{pid}/Account/{aid}")]
public class AccountsController: ControllerBase 
{
    [HttpGet]
    public IEnumerable<string> Get(string cid, string eid, string pid, string aid)
    {
        return new string[] { "value1", "value2" };
    }
}

因此,您只需在 controller 路由中添加完整路径,而不是继承 controller。

如果继承一个 controller 使路由也被继承,那将来可能是个问题。 图片有人更改了一个 controller 以继承一个新的 controller (从而引入了一条新的路由到 url)。 这不仅会影响您正在更改的 controller,还会影响所有孩子。

在我看来,最好不要有可能影响路线外观的外部事物。 只有 controller 中的 [Route] 可以更改它。 它更简单、更容易找到受影响的内容、更易于维护、更明确,inheritance 或外部代码不会隐藏任何内容。

问题是:您真的需要路线中的完整路径吗? 为什么不改用这个:

  • api/公司/{cid}
  • api/员工/{eid}
  • api/产品/{pid}
  • api/帐户/{aid}

这是你应该做出的决定。

作为旁注,您可以考虑返回IActionResult而不是实际的对象。 此外,您可能希望在参数中使用[FromRoute] 最后,我在操作方法名称中使用了复数,因为它返回一个数组,但如果您在路由中提供id ,则表明您返回的是单个实体,而不是数组。

我鼓励您阅读ASP.NET 核心属性路由

暂无
暂无

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

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