Asp.net核心路由与多个可选参数调用不同的动作

问题描述 投票:0回答:2

在Asp.net WebApi2中

调用api / values / 9b858599-7639-45da-acd6-a1323fb019b5时调用Action。

使用可选参数的操作。

当api / values / 9b858599-7639-45da-acd6-a1323fb019b5?maxRecords = 100或api / values /?maxRecords = 100 GetProducts调用Action。

在Asp.net核心

但是在asp.net核心中调用api / values / 9b858599-7639-45da-acd6-a1323fb019b5时,会调用GetProducts Action。我想在不改变现有网址的情况下调用Get动作。

如何在Asp.net core 2.0中解决此问题

调节器

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5
    [HttpGet("{productId:Guid}", Order = 1)]
    public ActionResult<string> Get(Guid productId)
    {
        return "value1";
    }


    //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100
    //https://localhost:44323/api/values/?maxRecords=100
    [HttpGet("{startRecordId:Guid?}")]
    public ActionResult<IEnumerable<string>> GetProducts(Guid? startRecordId, int maxRecords, DateTimeOffset? minimumChangeDate = null)
    {
        return new string[] { "value1", "value2" };

    }

}

Startup.cs

app.UseMvc(routes =>
        {
            routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
            routes.MapRoute("DefaultApi", "api/{controller}/{id?}");
        });
asp.net-core asp.net-core-2.2 asp.net-core-routing
2个回答
1
投票

虽然不理想,这是一个临时的鞋拔,直到你可以更新客户端电话。你可以尝试这个,如果你可以假设你必须有一个maxRecords QueryString。因为如果它默认为0则没用,除非你在0的情况下有逻辑。

    //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5
    [HttpGet("{productId:Guid}", Order = 1)]
    public ActionResult<string> Get(Guid productId)
    {
        return "value1";
    }


    //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100
    //https://localhost:44323/api/values/?maxRecords=100
    [HttpGet("{startRecordId:Guid?}")]
    public ActionResult<IEnumerable<string>> GetProducts(Guid? startRecordId, [FromQuery] int maxRecords, [FromQuery] DateTimeOffset? minimumChangeDate = null)
    {
        if (!Request.GetDisplayUrl().Contains(nameof(maxRecords)) &&
            startRecordId.HasValue)
        {
            return Get(startRecordId.Value);
        }

        return new string[] { "value1", "value2" };

    }

0
投票

您的URI不遵循RESTful约定。坦率地说,我看不出你是如何做到这一点的,因为同样的问题应该导致ASP.NET Web Api,但是你可能会对在ASP.NET中完成路由的方式感到幸运。 Web Api。 ASP.NET Core完全不同地处理路由。

无论如何,多个产品列表的路由不应在实际URI中包含id。换一种说法:

/api/values - Multiple values
/api/values/{id} - Single value

对于过滤,排序等多条记录,这些记录应该是查询字符串的一部分。这包括像startRecordId

/api/values?startRecordId={id}

消除路线中的歧义,你就没有问题。长和短,你不能有两条路线都在同一路径段接受Guid,即使它是一个可选的。将startRecordId移动到查询字符串中,无论如何这是正确的方法,你很高兴。


0
投票

您可以根据哪些参数具有提供的值来组合您的操作并更改行为;

    //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5
    //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100
    //https://localhost:44323/api/values/?maxRecords=100
    [HttpGet("{startRecordId:Guid?}")]
    public ActionResult<IEnumerable<string>> GetProducts(Guid? startRecordId, int? maxRecords, DateTimeOffset? minimumChangeDate = null)
    {
        if (startRecordId.HasValue && !maxRecords.HasValue)
            return "value";
        else
            return new string[] { "value1", "value2" };

    }
© www.soinside.com 2019 - 2024. All rights reserved.