1

我有一个 ASP.NET Web API 应用程序,我想在其中响应以下路由:

1. http://localhost:1234/values
2. http://localhost:1234/values/123
3. http://localhost:1234/values/large
4. http://localhost:1234/values/small

注意:这些路线和示例只是示例。但它们映射到我想要实现的目标。

  1. 应该返回所有值,比如数字列表。
  2. 应该返回 id 为123的资源的值。
  3. 应该返回应用程序认为值的列表。不管那可能是什么。
  4. 应该返回应用程序认为值的列表。

与十亿个 ASP.NET Web Api 路由示例一样,数字 (1) 和 (2) 很简单。但是当我尝试解决(3)和(4)时,(1)和(2)不再起作用。

这是我目前的路线:

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // trying to map to "values/large" or "values/small"
        routes.MapHttpRoute(
            name: "ActionsApi",
            routeTemplate: "{controller}/{action}",
            defaults: null,
            constraints: new { action = @"^[a-zA-Z]+$" }
        );

        // trying to map to "values/123"
        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{controller}/{id}",
            defaults: null,
            constraints: new { id = @"^\d+$" }
        );

        // trying to map to "values"
        routes.MapHttpRoute(
            name: "ControllerApi",
            routeTemplate: "{controller}"
        );

通过上述路线,(3)和(4)工作。

(2) 回报:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
No action was found on the controller 'Values' that matches the name '123'.
</string>

并且(1)返回:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
Multiple actions were found that match the request:
System.Collections.Generic.IEnumerable`1[System.String] Get() on type MvcApplication3.Controllers.ValuesController
System.Collections.Generic.IEnumerable`1[System.String] Large() on type MvcApplication3.Controllers.ValuesController
System.Collections.Generic.IEnumerable`1[System.String] Small() on type MvcApplication3.Controllers.ValuesController
</string>

我不知道如何设置路由以支持上面列出的 4 个 API 示例。

编辑:感谢大卫,他指出 \w 也匹配数字,因此存在问题。我将其更改为 [a-zA-Z]+ 以匹配largesmall

现在除了(1)之外的所有工作。

编辑 2正如@andrei 所建议的,我将id参数设为可选,以尝试使 (1) 正常工作,但导致该路线出现以下错误:

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly. 

我在这里添加的可选默认值:

        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{controller}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new { id = @"^\d+$" }
        );
4

1 回答 1

1

您是否考虑过将路由保留为默认值,并处理控制器中的“值”?

例如,将您的 Get 更改为字符串类型的 id,然后检查控制器内的“特殊”值。

public class ValuesController : ApiController
    {

    // GET api/values/5
    public string Get(string id)
    {
        if (id == "large")
        {
            return "large value";
        }

        if (id == "small")
        {
            return "small value";
        }

        return "value " + id;
    }
}
于 2013-06-13T10:49:12.860 回答