ASP.NET MVC4 Web API控制器在一个路由上卡住了

3

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

/api/values/ => "value1","value2"
/api/values/1 => "value"
/api/scenario/ => "value1","value2"
/api/scenario/1 => "value1","value2"
                   ^^^^^^^^^^^^^^^^^
                   should return "value"!

使用断点,我知道/api/scenario/1实际上被发送到public IEnumerable<string> Get(),而不是预期的public string 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);
        }
    }
}

WebApiConfig.cs

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();
        }
    }
}

ValuesController.cs

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";
        }
    }
}

ScenarioController.cs(是的,它在Controllers文件夹中)

namespace RoutingTest.Controllers
{
    public class ScenarioController : ApiController
    {
        // GET api/scenario
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/scenario/5
        public string Get(int id)
        {
            return "value";
        }
    }
}
3个回答

2

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

> 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继承的类。)
(我并不是在讽刺你,我建议你全部重新构建,然后再试一次。)

谢谢你尝试复制它。是的,我已经重新启动并创建了新项目来复制我在另一个项目中看到的情况,当它出现相同问题时,我感到非常惊讶。已经进行了多次清理项目和全部重建操作 :( - Noel
我在asp.net mvc方面缺乏经验 - 是否还有其他因素可能会影响配置,导致出现这种情况?NuGet包?.NET 4.0与4.5? - Noel
刚刚创建了一个新的“解决方案”,使用相同的代码,现在可以正常工作了。 - Noel
1
这感觉像是服务器,可能是IIS或VS的内部服务器,仍然保留着旧版本。我应该先问一下你正在调试哪个服务器。 - Pete Klein
就我个人而言,我使用的是VS2012内部服务器。很奇怪,因为我可以更改其他服务并看到差异,但这个服务就是不会改变! - Noel

2

Gremlins。感谢@Pete Klien验证了代码在我的机器之外也能正常工作。这是我所做的。

  1. 在原始项目中遇到控制器只使用1个Get方法的问题。
  2. 创建新的Web Api项目,并使用我在问题中发布的代码。出现相同的症状。
  3. 清理项目,重新构建全部,仍然没有成功。
  4. 重启计算机,清理,重新构建,再次尝试,但仍然没有成功。
  5. 在新解决方案中创建新的Web Api项目,成功!

1
......还有,问题又出现了。我已经使用非工作项目的代码和配置来设置新解决方案,当测试第一个(新添加的)控制器时,发现同样存在只使用未参数化的Get方法的问题! - Noel
1
哎呀,孩子们,保持控制器方法参数名称和路由配置参数名称相同会有所帮助。 - Noel

0
我遇到了这个问题,但无法让任何东西正常工作。最终,我更改了IIS Express项目URL设置上的端口,一切都恢复正常了。原来是localhost:57846,我只需将其更改为localhost:57847,一切就恢复正常了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接