我正在将控制器从 .NET Framework 迁移到 .NET Core,并且希望与以前版本的 API 调用兼容。我在处理来自查询参数的多个路由时遇到问题。
我的示例控制器:
[Route("/api/[controller]")]
[Route("/api/[controller]/[action]")]
public class StaticFileController : ControllerBase
{
[HttpGet("{name}")]
public HttpResponseMessage GetByName(string name)
{
}
[HttpGet]
public IActionResult Get()
{
}
}
Calling api/StaticFile?name=someFunnyName
将引导我到Get()
action 而不是预期的 GetByName(string name)
.
我想要实现的目标:
- 调用 GET
api/StaticFile
-> 转到Get()
action
- 调用 GET
api/StaticFile?name=someFunnyName
-> 转到GetByName()
action
My app.UseEndpoints()
from Startup.cs
只有这些行:
endpoints.MapControllers();
endpoints.MapDefaultControllerRoute();
如果我使用[HttpGet]
到处并添加([FromQuery] string name)
它让我AmbiguousMatchException: The request matched multiple endpoints
感谢您花时间帮助我(也许还有其他人)
我想要实现的目标:
- 调用 GET api/StaticFile -> 转到 Get() 操作
- 调用 GET api/StaticFile?name=someFunnyName -> 转到 GetByName() 操作
为了实现上述基于查询字符串将请求与预期操作匹配的要求,您可以尝试实现自定义动作方法选择器属性 https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.actionconstraints.actionmethodselectorattribute?view=aspnetcore-3.1并将其应用到您的操作中,如下所示。
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class QueryStringConstraintAttribute : ActionMethodSelectorAttribute
{
public string QueryStingName { get; set; }
public bool CanPass { get; set; }
public QueryStringConstraintAttribute(string qname, bool canpass)
{
QueryStingName = qname;
CanPass = canpass;
}
public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
{
StringValues value;
routeContext.HttpContext.Request.Query.TryGetValue(QueryStingName, out value);
if (QueryStingName == "" && CanPass)
{
return true;
}
else
{
if (CanPass)
{
return !StringValues.IsNullOrEmpty(value);
}
return StringValues.IsNullOrEmpty(value);
}
}
}
应用于行动
[Route("api/[controller]")]
[ApiController]
public class StaticFileController : ControllerBase
{
[HttpGet]
[QueryStringConstraint("name", true)]
[QueryStringConstraint("", false)]
public IActionResult GetByName(string name)
{
return Ok("From `GetByName` Action");
}
[HttpGet]
[QueryStringConstraint("name", false)]
[QueryStringConstraint("", true)]
public IActionResult Get()
{
return Ok("From `Get` Action");
}
}
测试结果
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)