【问题标题】:Custom route with action in the controller控制器中带有动作的自定义路由
【发布时间】:2013-03-27 00:09:29
【问题描述】:

在我的RouteConfig 我有:

public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

  routes.MapRoute("ApiController", "api/{controller}");

  routes.MapRoute("ApiControllerAndIntegerId", "api/{controller}/{id}", null, new { id = @"^\d+$" });

  routes.MapRoute("ApiControllerActions", "api/{controller}/{action}");
}

然后我有一个LookupController

public class LookupsController : ApiController
{
  public string Get()
  {
    return "Default Get";
  }
  // /api/lookups/custom
  [ActionName("custom")]
  public string CustomLookup()
  {
    return "Hello, World";
  }
}

如果我导航到/api/lookups/custom,我仍然会得到Default Get 而不是Hello, World。我做错了什么?

编辑

我尝试了MapHttpRouteMapRoute 的不同变体。两者似乎都不起作用。

【问题讨论】:

  • 对于初学者,您应该使用MapHttpRoute,因为这是用于 Web API 路由,MapRoute 用于 ASP.NET MVC。比尝试更改路线顺序(首先是最具体的路线),您可能会得到您想要的。
  • @tpeczek 在我正在观看的培训视频之后,培训师执行File > New > MVC 4 Web Application > Web APIMapRouteRoutesConfig 中的默认值。这是错的吗?
  • 此模板同时使用 ASP.NET MVC(用于表示层)和 ASP.NET Web API(用于 API 层),因此您可以看到这两种方法。事实上,这是两种不同的技术。这让我想到了下一个问题。您从哪个命名空间使用ActionNameAttribute?对于 Web API,它应该是 System.Web.Http(但 ASP.NET MVC 在 System.Web.Mvc 命名空间中有自己的版本)。记住路线顺序,在这里阅读更多:stackoverflow.com/questions/15553620/…
  • @tpeczek ActionNameAttribute 在这种情况下来自 System.Web.Http

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


【解决方案1】:

MVC 路由按照您定义它们的顺序进行检查。您在使用/api/lookups/custom 时遇到了问题,它应该是"api/{controller}/{action}"。但是,在此之前你有"api/{controller}/{id}""api/{controller}",所以看起来其中之一正在捕捉它。我的猜测是它试图在这两个中的第一个中将“自定义”解析为{id}。我注意到您没有在路由中指定默认控制器或操作;您可能会在发布之前将它们取出以减少空间,但如果您没有指定默认值,我建议您这样做 - 无论它是否能够选择自己的默认值,知道 你的程序“我不知道该怎么做”的行为是什么。

颠倒您指定这三个路线的顺序。如有疑问,请将最长和最具体的路线放在首位,然后逐渐变得更加模糊。将更通用的路由置于顶部往往会导致这些路由捕获本应进一步向下进行更具体的路由定义的东西。

【讨论】:

  • 我没有默认路由,我正在遵循的教程明确表示出于某种原因将其删除。多亏了这篇文章,我对路由有了更多的了解,所以+1。我已经关注了下面的帖子,它或多或少地将您的答案翻译成代码,但我仍然遇到同样的问题。
  • 我没有说默认路由 - 我说为您的特定路由添加默认值。您的路线包含 {controller} 之类的内容,但您从不为它们指定默认值。将"ApiControllerActions" 路由放在首位会发生什么?
  • 对了!当它是第一个时,它仍然加载DefaultGet... :(
【解决方案2】:

您为 Web Api 使用了错误的配置路由,它应该是 MapHttpRoute 而不是 MapRoute

var configuration = GlobalConfiguration.Configuration;

     configuration.Routes.MapHttpRoute(
          name: "CustomizedApi",
          routeTemplate: "api/{controller}/{action}/{id}",
          defaults: new { id = RouteParameter.Optional }
      );

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

请注意:将路由"api/{controller}/{action}/{id}"放在"api/{controller}/{id}"之上

另外,在您的CustomLookup 中标记[HttpGet] 以支持此操作的GET 方法:

// /api/lookups/get
public string Get()
{
    return "Default Get";
}

// /api/lookups/custom
[ActionName("custom")]
[HttpGet]
public string CustomLookup()
{
    return "Hello, World";
}

会有用的

【讨论】:

  • 感谢您的回答,我已经更新了我的问题。两种方法我都试过了
  • @LukeHennerley:将"api/{controller}/{action}/{id}" 放在路线顶部
  • 不幸的是,仍然无法正常工作。似乎没有注册路线?在这种情况下,configuration 是什么?
  • 再次感谢,但现在我得到以下异常:Multiple actions were found that match the request: System.String Get() on type CodeCamper.Web.Controllers.LookupsController System.String CustomLookup() on type CodeCamper.Web.Controllers.LookupsController
  • @LukeHennerley:这很奇怪,我已经手动完成了,您能否更新您的问题以反映您在做什么?以及你得到这个感觉的网址
猜你喜欢
  • 2016-04-05
  • 1970-01-01
  • 2011-12-03
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 2012-06-19
  • 2013-08-23
  • 1970-01-01
相关资源
最近更新 更多