首页 > 解决方案 > 如何在路由解析中包含查询字符串以允许具有相同方法、路由和查询字符串的多个操作?

问题描述

我正在将 ASP.NET MVC (.NET Framework) 应用程序转换为 ASP.NET Core MVC。这严格来说是一种转换,我无法进行任何重大更改,因此我无法更改任何路线或方法。我无法匹配 ASP.NET Core MVC 中的相同功能。

工作 ASP.NET MVC:

  [HttpPut]
  [Route("status")]
  public async Task<IHttpActionResult> UpdateStatusByOrderGuid([FromUri] Guid orderGUID, [FromBody] POST_Status linkStatusModel)
  {

  }

  [HttpPut]
  [Route("status")]
  public async Task<IHttpActionResult> UpdateStatusById([FromUri] Guid id, [FromBody] POST_Status linkStatusModel)
  {

  }

不工作,ASP.NET Core MVC。

我收到一个错误:

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:请求匹配多个端点

代码:

    [HttpPut]
    [Route("status")]
    public async Task<IActionResult> UpdateStatusByOrderGuid([FromQuery] Guid orderGUID, [FromBody] POST_Status statusModel)
    {

    }

    [HttpPut]
    [Route("status")]
    public async Task<IActionResult> UpdateStatusById([FromQuery] Guid id, [FromBody] POST_Status statusModel)
    {

    }

当它解析哪个路由时,我需要包含查询参数。它应该根据是否orderGUIDid查询字符串中进行匹配。

谢谢。

标签: asp.net-mvcasp.net-core-mvc

解决方案


您需要自定义ActionMethodSelectorAttribute

1.QueryStringConstraint属性:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class QueryStringConstraintAttribute : ActionMethodSelectorAttribute
{
    public string ValueName { get; private set; }
    public bool ValuePresent { get; private set; }
    public QueryStringConstraintAttribute(string valueName, bool valuePresent)
    {
        this.ValueName = valueName;
        this.ValuePresent = valuePresent;
    }
    public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
    {
        var value = routeContext.HttpContext.Request.Query[this.ValueName];
        if (this.ValuePresent)
        {
            return !StringValues.IsNullOrEmpty(value);
        }
        return StringValues.IsNullOrEmpty(value);
    }
}

2.控制器:

[HttpPut]
[Route("status")]
[QueryStringConstraint("orderGUID",true)]
[QueryStringConstraint("id", false)]
public void UpdateStatusByOrderGuid([FromQuery] Guid orderGUID,[FromBody]POST_Status model)
{

}

[HttpPut]
[Route("status")]
[QueryStringConstraint("id", true)]
[QueryStringConstraint("orderGUID", false)]
public void UpdateStatusById([FromQuery] Guid id, [FromBody]POST_Status model)
{

}

3.启动.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //...
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

结果: 在此处输入图像描述


推荐阅读