C# ASP.NET MVC4 Web API控制器卡在一条路由上

C# ASP.NET MVC4 Web API控制器卡在一条路由上,c#,asp.net-mvc,asp.net-mvc-4,asp.net-web-api,asp.net-web-api-routing,C#,Asp.net Mvc,Asp.net Mvc 4,Asp.net Web Api,Asp.net Web Api Routing,我创建了一个新的ASP.NET MVC4 Web Api项目。除了默认的valuescoontroller,我还添加了另一个控制器ScenarioController。它的方法与值控制器完全相同。但由于某些原因,它的行为有所不同 /api/values/ => "value1","value2" /api/values/1 => "value" /api/scenario/ => "value1","value2" /api/scenario/1 => "value1",

我创建了一个新的ASP.NET MVC4 Web Api项目。除了默认的
valuescoontroller
,我还添加了另一个控制器
ScenarioController
。它的方法与
值控制器
完全相同。但由于某些原因,它的行为有所不同

/api/values/ => "value1","value2"
/api/values/1 => "value"
/api/scenario/ => "value1","value2"
/api/scenario/1 => "value1","value2"
                   ^^^^^^^^^^^^^^^^^
                   should return "value"!
使用断点,我知道
/api/scenario/1
实际上被发送到
公共IEnumerable Get()
,而不是预期的
公共字符串Get(int id)
。为什么?

以下是相关文件供参考(这些是原始的默认mvc4 webapi类,未修改任何内容):

Global.asax.cs

namespace RoutingTest
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
}
namespace RoutingTest
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
            // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
            // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
            //config.EnableQuerySupport();

            // To disable tracing in your application, please comment out or remove the following line of code
            // For more information, refer to: http://www.asp.net/web-api
            config.EnableSystemDiagnosticsTracing();
        }
    }
}
namespace RoutingTest.Controllers
{
    public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }
    }
}
WebApiConfig.cs

namespace RoutingTest
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
}
namespace RoutingTest
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
            // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
            // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
            //config.EnableQuerySupport();

            // To disable tracing in your application, please comment out or remove the following line of code
            // For more information, refer to: http://www.asp.net/web-api
            config.EnableSystemDiagnosticsTracing();
        }
    }
}
namespace RoutingTest.Controllers
{
    public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }
    }
}
名称空间路由测试
{
公共静态类WebApiConfig
{
公共静态无效寄存器(HttpConfiguration配置)
{
config.Routes.MapHttpRoute(
名称:“DefaultApi”,
routeTemplate:“api/{controller}/{id}”,
默认值:新建{id=RouteParameter.Optional}
);
//取消注释以下代码行,以启用对具有IQueryable或IQueryable返回类型的操作的查询支持。
//要避免处理意外或恶意查询,请使用QueryableAttribute上的验证设置验证传入的查询。
//有关更多信息,请访问http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();
//要在应用程序中禁用跟踪,请注释掉或删除以下代码行
//有关更多信息,请参阅:http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
}
}
}
值控制器.cs

namespace RoutingTest
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
}
namespace RoutingTest
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
            // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
            // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
            //config.EnableQuerySupport();

            // To disable tracing in your application, please comment out or remove the following line of code
            // For more information, refer to: http://www.asp.net/web-api
            config.EnableSystemDiagnosticsTracing();
        }
    }
}
namespace RoutingTest.Controllers
{
    public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }
    }
}
名称空间路由测试控制器
{
公共类值控制器:ApiController
{
//获取api/值
公共IEnumerable Get()
{
返回新字符串[]{“value1”,“value2”};
}
//获取api/values/5
公共字符串Get(int-id)
{
返回“值”;
}
}
}
ScenarioController.cs(是的,它在Controllers文件夹中)

名称空间路由测试控制器
{
公共类场景控制器:ApiController
{
//获取api/场景
公共IEnumerable Get()
{
返回新字符串[]{“value1”,“value2”};
}
//获取api/scenario/5
公共字符串Get(int-id)
{
返回“值”;
}
}
}

我刚刚尝试了你的代码,得到了预期的结果:

> curl http://localhost:53803/api/values
["value1","value2"]
> curl http://localhost:53803/api/values/1
"value"
> curl http://localhost:53803/api/scenario
["value1","value2"]
> curl http://localhost:53803/api/scenario/1
"value"
>
(顺便说一句,它不需要位于
Controllers
文件夹中。
HttpConfiguration.Routes.MapHttpRoute
只需查找从
ApiController
继承的所有类)


当我建议你重建所有并再试一次时,我并不是在讽刺。

小精灵们。感谢@Pete Klien验证代码是否在我的机器之外工作。这就是我所做的

  • 在原始项目中,仅使用1种方法获取控制器遇到的问题
  • 创建了一个新的WebAPI项目,其中包含我在问题中发布的代码。同样的症状
  • 清理项目,全部重建,仍然没有骰子
  • 重新启动机器,清理,重建,再试一次,没有骰子
  • 在新解决方案中创建新的Web Api项目,成功
    我遇到了这个问题,无法让任何东西正常工作。最后,我更改了IIS Express项目Url设置上的端口,一切都恢复正常。是本地主机:57846。我刚刚制作了localhost:57847,一切都恢复正常。

    感谢您尝试复制它。是的,我重新启动并创建了一个新项目来复制我在另一个项目中看到的内容,当它做同样的事情时,我感到相当惊讶。许多清洁项目和重建工作都已完成:(我没有asp.net mvc方面的经验--是否还有其他任何东西会影响配置,从而导致这种情况发生?NuGet package?.net 4.0 vs 4.5?刚刚创建了一个新的解决方案,使用相同的代码,并且工作正常。这感觉像是服务器(IIS或vs的内部服务器)保留了旧版本。我应该问一下ed你在哪个服务器上调试。FWIW,我在使用VS2012内部服务器。这很奇怪,因为我可以更改其他服务并看到差异,但这一个不会更改!…aaaaaa,问题又回来了。我一直在使用非工作项目中的代码和配置设置新的解决方案,在测试第一个服务时(新添加的)控制器,发现了仅使用非参数化Get方法的相同问题!welp,它有助于保持控制器方法参数名称和路由配置参数名称相同,kids。