无法在Asp.NET MVC中命中Api路由

时间:2014-10-02 13:24:11

标签: c# asp.net-mvc

我有一个ASP.NET MVC应用程序。我正在为这个应用添加一些API。我的一些API工作。其他人没有。我遇到的问题是我不知道。我应该使用什么路线或b。如果我没有正确注册路线。例如,我有以下WebApi:

namespace MyProject.Controllers
{
    public class ProjectApiController : System.Web.Http.ApiController
    {
        [ResponseType(typeof(IEnumerable<Product>))]
        public IHttpActionResult Get(string search, int max)
        {
            // Clean up the query
            string query = q.Trim().ToLower();

            // Get the products
            List<Product> products = Product.GetAll();
            var results = (from product in products
                           where product.Name.ToLower().Contains(query)
                           select new
                           {
                               Id = product.Id,
                               Name = product.Name
                           }).Take(max);

            // Return the results
            return Ok(results);
        }

        [ResponseType(typeof(IEnumerable<Category>))]
        public async Task<IHttpActionResult> GetCategories(string search, int max)
        {
            // Clean up the query
            string query = q.Trim().ToLower();

            // Get the products
            List<Category> products = Category.GetAll();
            var results = (from category in categories
                           where category.Name.ToLower().Contains(query)
                           select new
                           {
                               Id = category.Id,
                               Name = category.Name
                           }).Take(max);

            // Return the results
            return Ok(results);
        }
    }
}

当我访问/api/projectApi?search=tes&max=5时,我会像我想要的那样返回一个JSON数组,如果第二种方法被注释掉的话。如果第二种方法未被注释,我会收到一条错误消息:

"Message":"An error has occurred.","ExceptionMessage":"Multiple actions were found that match the request: \r\nGet on type MyProject.Controllers.ProjectApiController\r\nGetCategories on type MyProject.Controllers.PrjectApiController","ExceptionType":"System.InvalidOperationException","StackTrace":"   at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n   at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n   at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"}

理想情况下,我希望能够致电:

/api/projectApi/projects?search=tes&max=5 AND

/api/projectApi/categories?search=tes&max=5

然而,我似乎无法弄清楚如何做到这一点。我做错了什么?

谢谢!

3 个答案:

答案 0 :(得分:1)

如果您使用ASP.NET api 2,您现在也可以使用路由属性来装饰您的方法,例如

[Route("/api/projectApi/products")]
[ResponseType(typeof(IEnumerable<Product>))]
public IHttpActionResult Get(string search, int max)
{ ...
}

[Route("/api/projectApi/categories")]
[ResponseType(typeof(IEnumerable<Category>))]
public async Task<IHttpActionResult> GetCategories(string search, int max)
{ ...
}

请参阅http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

答案 1 :(得分:0)

致电

/api/projectApi?search=tes&max=5

路由不知道要给出哪种方法,因为你没有指定动作,只有控制器和参数,这两种方法都是相同的。

要解决此问题,请添加此路由

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{search}/{max}",
            defaults: new { search = RouteParameter.Optional, max = RouteParameter.Optional }
        );

现在这些路线将起作用

/api/projectApi/Get/tes/5 
/api/projectApi/GetCategories/tes/5

答案 2 :(得分:0)

将api控制器添加到我的mvc projetct时遇到了同样的问题。在我的情况下,我错过了这个&#34; GlobalConfiguration.Configure(WebApiConfig.Register);&#34;在我的Global.asax。

我的样子如下:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }