ASP.NET Web API路由不映射到控制器操作

时间:2013-06-13 08:09:00

标签: c# asp.net-mvc asp.net-web-api

我有一个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. 应该返回应用程序认为值的列表。
  5. 与十亿个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] +以匹配 large small

    现在所有工作除了(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+$" }
            );
    

1 个答案:

答案 0 :(得分:1)

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

e.g。 将您的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;
    }
}