Web Api 具有可选参数和查询参数的属性路由

Web Api Attribute Routing with optional parameters and query parameters

我有这个网络 api 控制器:

[RoutePrefix("api/product")]
public class ProductController : ApiController
{
    [HttpGet, Route("{id?}")]
    public async Task<HttpResponseMessage> GetProduct([FromUri] string param1 = null, [FromUri] string param2 = null, Guid? id = null)
    {
        ...     
    }
}

我想通过这些 uri 访问 :
api/product/?param1=something¶m2=smt

api/product/7b55fcee-21e7-4b10-80e3-42b4d9cf913d?param1=something¶m2=smt

但是,第一个 uri 不起作用,未设置路由参数的默认值。
这个 uri 有效:
api/product/null?param1=something¶m2=smt
不是这个 :
api/product/?param1=something¶m2=smt

我尝试使用 "string" 类型作为路由参数,但仍然无效。

是参数的顺序吗?
还是我对 Web Api 路由映射有什么误解?

编辑: 我的 WebApiConfig.cs 不包含默认路由:

public static class EdmWebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
       if (config == null) throw new ArgumentNullException(nameof(config));

       // Attribute routing
       config.MapHttpAttributeRoutes();

       ...
       some declaration of formatters
       ...
    }
}

我应该声明默认路由吗?
在我看来,因为我使用了属性映射,所以我不需要这样做。

我试过那样改变我的路由:

[RoutePrefix("api")]
public class ProductController : ApiController
{

    [HttpGet, Route("product/get/{id?}")]
    public async Task<HttpResponseMessage> GetProduct([FromUri] Guid param1, [FromUri] string param2, Guid? id = null)
    {
      ...
    }
}

这个 uri api/product/get/?param1=something¶m2=smt 仍然不起作用。
(我尝试了 api/product/?param1=something¶m2=smt 与相关的路由,不工作)

我需要在 WebApiConfig.cs 中声明默认路由吗?
你在WebApiConfig.cs中能做的,你应该能在属性路由中做,不是吗?像可选参数、约束、...

您的路由前缀过于具体。我相信你想要:

[RoutePrefix("api")]
public class ProductController : ApiController
{
    [HttpGet, Route("product/{id?}")]
    public async Task<HttpResponseMessage> GetProduct([FromUri] string param1 = null, [FromUri] string param2 = null, Guid? id = null)
    {
        ...     
    }
}

哪个应该适合您。路由 prefix 本身并不是路由,因此默认路由应该不那么具体。

我无法重建此错误,但我想推荐一个更好的模式供您遵循。

您的单一方法过于笼统,需要在执行实际工作之前对参数进行主要检查。

如果您有两个独立的端点,那就更好了。 通用 Get 方法,例如:

Get([FromUri] string keyword = null)

还有一个如:

GetById(Guid id)

您设置 RoutePrefix 的方式是正确的,无需更改。