【问题标题】:How to overload controller methods with same number of arguments in ASP.NET Core Web API?如何在 ASP.NET Core Web API 中重载具有相同数量参数的控制器方法?
【发布时间】:2019-08-29 08:33:03
【问题描述】:

我正在将一个完整的 .NET Framework Web API 2 REST 项目迁移到 ASP.NET Core 2.2 并且在路由中有点迷失。

在 Web API 2 中,我能够根据参数类型使用相同数量的参数重载路由,例如我可以有Customer.Get(int ContactId)Customer.Get(DateTime includeCustomersCreatedSince) 并且传入的请求将被相应地路由。

我无法在 .NET Core 中实现相同的功能,我收到 405 错误或 404 错误:

"{\"error\":\"请求匹配多个端点。匹配项:\r\n\r\n[AssemblyName].Controllers.CustomerController.Get ([AssemblyName])\r\n[AssemblyName].Controllers.CustomerController.Get ([AssemblyName])\"}"

这是我完整的 .NET 框架应用程序 Web API 2 应用程序中的工作代码:

[RequireHttps]    
public class CustomerController : ApiController
{
    [HttpGet]
    [ResponseType(typeof(CustomerForWeb))]
    public async Task<IHttpActionResult> Get(int contactId)
    {
       // some code
    }

    [HttpGet]
    [ResponseType(typeof(List<CustomerForWeb>))]
    public async Task<IHttpActionResult> Get(DateTime includeCustomersCreatedSince)
    {
        // some other code
    }
}

这就是我在 Core 2.2 中将其转换为的内容:

[Produces("application/json")]
[RequireHttps]
[Route("api/[controller]")]
[ApiController]
public class CustomerController : Controller
{
    public async Task<ActionResult<CustomerForWeb>> Get([FromQuery] int contactId)
    {
        // some code
    }

    public async Task<ActionResult<List<CustomerForWeb>>> Get([FromQuery] DateTime includeCustomersCreatedSince)
    {
        // some code
    }
}

如果我注释掉其中一个Get 方法,上面的代码就可以工作,但是一旦我有两个Get 方法就会失败。我希望 FromQuery 使用请求中的参数名称来引导路由,但似乎不是这样?

是否可以重载像这样的控制器方法,其中您具有相同数量的参数,并且基于参数的类型或参数的名称进行路由?

【问题讨论】:

    标签: routing asp.net-core-webapi asp.net-web-api-routing asp.net-core-2.2


    【解决方案1】:

    你不能做动作重载。路由在 ASP.NET Core 中的工作方式与在 ASP.NET Web Api 中的工作方式不同。但是,您可以简单地组合这些操作,然后在内部进行分支,因为所有参数都是可选的:

    public async Task<ActionResult<CustomerForWeb>> Get(int contactId, DateTime includeCustomersCreatedSince)
    {
        if (contactId != default)
        {
            ...
        }
        else if (includedCustomersCreatedSince != default)
        {
            ...
        }
    }
    

    【讨论】:

    • 啊,这就解释了!如果你有两个相同类型的参数会发生什么,例如Get(int companyId, int personId) 并且您只想使用 personId,您需要致电 Customer/Get?personId=1234 吗? IE。路由是使用参数的类型还是参数名进行匹配?
    • 是的。它将通过名称绑定。
    • 我不明白他们为什么不能为不同的参数重载方法......当你处理可以组合在一起的QueryString参数时,制作If/else-if/else-if/..../else是非常不愉快的...
    猜你喜欢
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 2018-07-09
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多