26

我正在尝试在我的 MVC4 WebAPI 项目中配置路由。

我希望能够根据产品名称或类型搜索产品,如下所示:

/api/products?name=WidgetX- 返回所有名为 WidgetX /api/products?type=gadget的产品 - 返回所有类型为小工具的产品

路由配置如下:

config.Routes.MapHttpRoute(
    name: "Get by name",
    routeTemplate: "api/products/{name}",
    defaults: new { controller = "ProductSearchApi", action = "GetProductsByName", name = string.Empty }
);

config.Routes.MapHttpRoute(
    name: "Get by type",
    routeTemplate: "api/products/{type}",
    defaults: new { controller = "ProductSearchApi", action = "GetProductsByType", type = string.Empty }
);

问题是查询字符串参数的名称似乎被忽略了,所以第一个路由总是使用的,不管查询字符串参数的名称。如何修改路线以使其正确?

4

4 回答 4

31

您只需要以下一条路由,因为查询字符串不用作路由参数:

config.Routes.MapHttpRoute(
    name: "Get Products",
    routeTemplate: "api/products",
    defaults: new { controller = "ProductSearchApi" }
);

然后定义两个方法,如下所示:

GetProductsByName(string name)
{}

GetProductsByType(string type)
{}

路由机制足够聪明,可以根据查询字符串的名称是否与输入参数相同,将您的 url 路由到您的正确操作。当然,所有带前缀的方法都是Get

您可能需要阅读以下内容: http ://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

于 2012-09-27T11:23:43.930 回答
5

您不需要在路由中包含查询参数。应该只有一个简单的路由映射来覆盖所有 ApiController 上的 Http 方法:

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

唯一需要调整路线的情况是,如果您想将参数移动到实际路径中,您似乎并没有这样做。那么您GET通过两个字段搜索的 http 方法将是:

public IEnumerable<Product> Get(string name, string type){
    //..your code will have to deal with nulls of each parameter
}

如果您想一次显式地搜索一个字段,那么您应该考虑将不同的控制器用于不同的目的。即,SearchProductByTypeController具有单一Get(string type)方法的一个。然后路由将是 /api/SearchProductByTypeController?type=gadget

于 2012-09-27T11:04:39.223 回答
0

尝试string.Empty改变RouteParameter.Optional

于 2012-09-27T10:56:32.143 回答
0

你确定控制器没问题?我的意思是,参数的名称。

    public string GetProductsByName(string name)
    {
        return "Requested name: " + name;
    }

    public string GetProductsByType(string type)
    {
        return "Requested type: " + type;
    }
于 2012-09-27T11:06:11.423 回答