C# 基于查询字符串参数名称的路由

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12619587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:54:41  来源:igfitidea点击:

Routing based on query string parameter name

c#asp.net-web-apiquery-stringasp.net-web-api-routing

提问by rickythefox

I'm trying to configure routing in my MVC4 WebAPI project.

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

I want to be able to search for products based on their name or their type like so:

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

/api/products?name=WidgetX- returns all products named WidgetX /api/products?type=gadget- returns all products of type gadget

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

The routes are configured like this:

路由配置如下:

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 }
);

The problem is that the name of the query string parameter seems to be ignored so the first route is always the one used, regardless the name of the query string parameter. How can I modify my route to get it right?

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

采纳答案by cuongle

What you need is just only one route below because query string is not used as routing parameters:

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

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

And, then define two methods like below:

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

GetProductsByName(string name)
{}

GetProductsByType(string type)
{}

Routing mechanism is smartenough to route your url to your correct action based on the name of query string whether the same with input parameters. Of course on all methods with prefix are Get

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

You might need to read this: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

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

回答by hagensoft

try changing string.Emptyfor RouteParameter.Optional

尝试更改string.EmptyRouteParameter.Optional

回答by Nick

You don't need to include your query parameters in the route. There should only be one simple route map to cover the Http Methods on all of your ApiControllers:

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

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

The only time you need to adjust the routes is if you want to move a parameter into the actual path, which you don't seem to be doing. Then your GEThttp method to search by two fields would be:

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

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

If you want to explicitly search by one field at a time then you should think about using different controllers for different purposes. Ie, a SearchProductByTypeControllerthat has a single Get(string type)method. The route would then be /api/SearchProductByTypeController?type=gadget

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

回答by laszlokiss88

Are you sure that the controllers are ok? I mean, the name of the params.

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

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

    public string GetProductsByType(string type)
    {
        return "Requested type: " + type;
    }