【问题标题】:Asp.net core Routing with multiple optional parameters calling different action具有多个可选参数调用不同操作的 Asp.net core 路由
【发布时间】:2019-01-30 17:00:31
【问题描述】:

在 Asp.net WebApi2 中

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

带有可选参数的操作。

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

在 Asp.net Core 中

但在 asp.net 核心中,当调用 api/values/9b858599-7639-45da-acd6-a1323fb019b5 时,会调用 GetProducts 操作。我想在不更改现有网址的情况下调用 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?}");
        });

【问题讨论】:

    标签: c# asp.net-core asp.net-core-2.2 asp.net-core-routing


    【解决方案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" };
    
        }
    

    【讨论】:

    • 我从 Request.Path.Value 更改为 Request.GetDisplayUrl()。 Request.Path 仅提供 Request.GetDisplayUrl() 提供具有 maxrecords 的整个 url 的路由。感谢上述方法暂时解决了我的问题,直到我的客户得到更新。
    • 根据您的评论更新了答案!
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      您的 URI 未遵循 RESTful 约定。坦率地说,我一开始看不到你是如何完成这项工作的,因为同样的问题应该导致 ASP.NET Web Api,但你可能只是幸运地看到了在 ASP.NET 中完成路由的方式网络 API。 ASP.NET Core 处理路由的方式完全不同。

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

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

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

      /api/values?startRecordId={id}
      

      消除路线中的歧义,您不会有任何问题。总而言之,您不能在同一路径段中有两条路线都接受Guid,即使它是可选的。将startRecordId 移动到查询字符串中,无论如何这是正确的方法,您可以开始了。

      【讨论】:

      • 我同意。我需要支持在路由中使用 startRecordId 的现有客户。所以我不能改变网址。是否有任何建议如何处理此类问题。
      • API 版本控制。旧客户端继续使用旧 API。你设置了一个弃用日期,然后那个日期落地,你就杀了它。
      • 这样,客户就有时间更新他们的代码,但 API 不断发展,您不能永远支持每个客户。
      • 版本控制在我的情况下可能不起作用。我正在将 Asp.net webapi 项目转换为 asp.net core,期望客户端不受影响,webapi 项目在服务器端转换为 asp.net core。
      猜你喜欢
      • 2021-10-30
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-04
      • 2014-04-08
      • 1970-01-01
      • 2014-10-18
      • 1970-01-01
      相关资源
      最近更新 更多