将所有Web API请求路由到一个控制器方法

msk*_*msk 12 asp.net asp.net-web-api-routing asp.net-web-api2

是否可以自定义ASP.NET Web API的路由机制,以将所有请求路由到一个控制器方法?

如果有请求进来

www.mysite.com/api/products/
Run Code Online (Sandbox Code Playgroud)

要么

www.mysite.com/api/otherResource/7
Run Code Online (Sandbox Code Playgroud)

所有这些都将被路由到我的SuperDuperController的Get()方法?

Kas*_*man 10

我遇到了一个需要这样做的案例.(Web API 2)

我首先考虑创建自定义IHttpControllerSelectorIHttpActionSelectors.然而,这有点模糊不清.所以我最终确定了这个死的简单实现.您所要做的就是设置通配符路由.例:

public class SuperDuperController : ApiController
{
    [Route("api/{*url}")]
    public HttpResponseMessage Get()
    {
        // url information
        Request.RequestUri
        // route values, including "url"
        Request.GetRouteData().Values
    }
}
Run Code Online (Sandbox Code Playgroud)

任何以"api /"开头的GET请求都将被路由到上述方法.这包括您问题中的上述网址.您必须自己从请求或上下文对象中挖掘出信息,因为这样可以绕过自动路由值和模型解析.

关于这一点的好处是你仍然可以使用其他控制器(只要它们的路由不以"api /"开头).


Jon*_*iak 4

我不知道你为什么要这样做,我当然不会建议通过一个控制器路由所有内容,但是你可以按如下方式实现这一点。假设您在调用中只会拥有带有可选 id 的资源,请将其添加到您的 WebApiConfig 中:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{resource}/{id}",
            defaults: new { controller = "SuperDuper", id = RouteParameter.Optional }
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

然后定义您的控制器方法,如下所示:

public class SuperDuperController : ApiController
{
    public IHttpActionResult Get(string resource, int? id = null)
    {
        return Ok();
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要IHttpActionResult为每种不同类型的资源决定适当的返回值。

或者使用属性路由,确保它config.MapHttpAttributeRoutes()存在于您的 WebApiConfig 中并将以下属性添加到您的控制器方法中:

[RoutePrefix("api")]
public class SuperDuperController : ApiController
{
    [Route("{resource}/{id?}")]
    public IHttpActionResult Get(string resource, int? id = null)
    {
        return Ok();
    }
}
Run Code Online (Sandbox Code Playgroud)