ASP.NET MVC WebAPI 404错误

时间:2013-12-16 22:01:20

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

我有一个在v4.0集成模式下运行的asp.net Web表单应用程序。

我尝试在App_Code文件夹中添加apicontroller。

在Global.asax中,我添加了以下代码

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

当我尝试在http://localhost/api/Value导航到控制器时,我收到404错误。

无扩展名网址在处理程序部分中配置。我为网站启用了表单和匿名身份验证。

ExtensionLess url配置为'*。'

当我点击控制器的url时,请求由StaticHandler而不是ExtensionlessUrlHandler-Integrated-4.0处理。

我现在不知道为什么系统会抛出错误,如下图所示。 Error

20 个答案:

答案 0 :(得分:106)

我遇到了这个问题。

我尝试编辑WebApiConfig.cs以满足此处的一些建议,并在其他地方编写示例代码。有些工作,但它没有解释为什么当WebApiConfig.cs完全按照MS模板WebApi项目编码时,路由无法正常工作。

我的实际问题是,在我的项目中手动添加WebApi时,我没有按照Global.asax

的配置调用的库存顺序
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        // This is where it "should" be
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        // The WebApi routes cannot be initialized here.
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

我可以猜测为什么会这样,但我没有进一步调查。至少可以说是不直观的。

答案 1 :(得分:32)

问题在于您的路由配置。 Mvc路由与WebApi路由不同。

添加对System.Web.Http.dllSystem.Web.Http.Webhost.dllSystem.Net.Http.dll的引用,然后按如下方式配置您的API路由:

   GlobalConfiguration.Configuration.Routes.MapHttpRoute(
     name: "DefaultApi",
     routeTemplate: "api/{controller}/{id}",
     defaults: new { id = System.Web.Http.RouteParameter.Optional }
   );

答案 2 :(得分:17)

确保以下事项

1.如果您的web api是IIS中的4.5安装4.5,请确保您的IIS配置了.NET 4.5或4.0

在命令提示符下使用管理员权限

运行此命令
C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regiis.exe -i

2.)将路线更改为

RouteTable.Routes.MapHttpRoute(
      name: "DefaultApi",
      routeTemplate: "{controller}/{id}",
      defaults: new { id = System.Web.Http.RouteParameter.Optional }
 );

并使用Demo / Get(其中demo是您的控制器名称)发出请求

如果1,2不工作试试3

3.)在web.config文件中添加以下配置

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />

</system.webServer>

答案 3 :(得分:10)

另外,请确保您的控制器以名称&#34; Controller&#34;如在&#34; PizzaPieController&#34;。

答案 4 :(得分:7)

我尝试了以上所有并遇到了同样的问题。事实证明,在IIS中创建的应用程序池默认为.net 2.0。当我将其更改为4.0然后再次工作

答案 5 :(得分:3)

还尝试删除整个api bin文件夹的内容。我的包含旧的dll(由于一个大的命名空间重命名)暴露了冲突的控制器。这些DLL没有被Visual Studio的Clean功能删除。

(但是,我发现asp.net web api严重缺乏调试级别的路由和调试信息。)

答案 6 :(得分:2)

感谢ShannonceinpapShri Guru,以下修改对我有用:

  1. public static void Register(HttpConfiguration config) { ... config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); }

    Global.asax.cs
  2. protected void Application_Start() { ... GlobalConfiguration.Configure(WebApiConfig.Register); RouteConfig.RegisterRoutes(RouteTable.Routes); ... }

    include using namespace std;
    
    int main() {
      float n1, n2, sum, diff, pro, quot;
      char f;
    
      cout << "PLease enter your function(A,S,D,M or X to end the program" << endl;
      cin >> f;
    
      while (f != 'A', 'S', 'D', 'M', 'X') {
        cout << "Invalid Operation" << endl;
        cout << "PLease enter your function(A,S,D,M or X to end the program"
             << endl;
        cin >> f;
      }
    
      if (f == 'X') return 0;
      if (f == 'A', 'S', 'D', 'M') {
        cout << "Please enter two numbers";
        cin >> n1 >> n2;
    
        if (f == 'A') {
          sum = n1 + n2;
          cout << sum;
        }
    
        else if (f == 'S') {
          if (n1 > n2) {
            diff = n1 - n2;
            cout << diff;
          } else {
            diff = n2 - n1;
            cout << diff;
          }
        } else if (f == 'D') {
          if (n1 > n2) {
            quot = n1 / n2;
            cout << quot;
          } else {
            quot = n2 / n1;
            cout << quot;
          }
        } else if (f == 'M') {
          pro = n1 * n2;
          cout << pro;
        }
      }
    
      return 0;
    }
    

答案 7 :(得分:2)

经过几个小时的花时间,我在我的案例中找到了解决方案。

这是在 RouteConfig 中注册路线的顺序。

我们应该在默认控制器路由之前在Route表中注册HttpRoute。它应该如下。 Route Config Route table configuration

  public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapHttpRoute(
             name: "DefaultApi",
             routeTemplate: "api/{controller}/{action}/{id}",
             defaults: new { id = RouteParameter.Optional }
         );
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

    }
}

答案 8 :(得分:2)

如果在App_Code中创建控制器,路由表如何知道它在哪里?您已将路由指定为“api / {controller / ...”,但这不是控制器所在的位置。尝试将其移动到正确的文件夹中。

答案 9 :(得分:2)

谢谢Shannon,效果很好=&gt;

我在Global.asax的订单是:

GlobalConfiguration.Configure(WebApiConfig.Register);  
RouteConfig.RegisterRoutes(RouteTable.Routes);

而不是好的:

RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register); 

答案 10 :(得分:1)

对于您尝试过的网址(http://localhost/api/Value),请确保其中包含一个名为ValueController的公共类型,该类型派生自ApiController并且有一些公共方法这些特点:

  • 方法名称以Get开头(例如GetValuesGet)。
  • 应用了该方法的HttpGet属性。

如果您尝试使用默认Web API项目模板中的代码,控制器的名称为ValuesController,而不是ValueController,因此网址为http://localhost/api/values

如果上述情况不合适,您可能需要enable tracing,这可以让您了解错误发生在管道中的位置(以及原因)。

希望这有帮助。

答案 11 :(得分:1)

我们也有这个,将.NET版本从4.5更改为4.5.1或更新解决了问题

答案 12 :(得分:1)

我将基于RouteAttribute的控制器dll复制到bin文件夹中,但它没有被识别为有效的控制器,我在客户端上收到404错误。

经过多次调试,我发现了我的问题。这是因为控制器引用的System.Web.Http.dll版本与主项目(包含global.asax.cs的版本)引用的System.Web.Http.dll版本不同。

Asp.Net使用像这样的代码通过反射找到控制器

internal static bool IsControllerType(Type t)
{
    return
        t != null &&
        t.IsClass &&
        t.IsVisible &&
        !t.IsAbstract &&
        typeof(IHttpController).IsAssignableFrom(t) &&
        HasValidControllerName(t);
}

由于IHttpController的每个版本的System.Web.Http.dll都不同,因此控制器和主项目必须具有相同的参考。

答案 13 :(得分:0)

我有时间将愚蠢的疏忽添加到列表中:我输入了错误的webapi默认路径路径。

原件:

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

修正:(观察“id”周围的花括号)

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

答案 14 :(得分:0)

以上解决方案都没有解决我的问题...我的错误是我将bin文件直接复制到生产服务器,然后,我不能工作。当我将项目发布到磁盘并复制&#34;已发布的&#34;文件夹到服务器。这有点明显,但是,可以帮助一些人。

答案 15 :(得分:0)

我很欣赏这是一个非常古老的问题,但我想我会为未来的用户添加另一个答案。

我发现这只发生在我正在处理的项目中,只有在它部署到CI / Staging之后才会发生。解决方案是在将每个版本部署到每个环境一次时来回切换编译debug =“true”值,并且它将自行修复。

答案 16 :(得分:0)

在我的情况下,我忘了将它从ApiController派生。

所以它看起来像

public class ValuesController : ApiController

答案 17 :(得分:0)

您的路线配置看起来不错。仔细检查web.config中的处理程序部分,对于集成模式,这是使用ExtensionLessUrlHandler的正确方法:

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

有关此主题的更多信息: http://blogs.msdn.com/b/tmarq/archive/2010/05/26/how-extensionless-urls-are-handled-by-asp-net-v4.aspx

答案 18 :(得分:0)

注册路线的顺序是我的Application_Start()中的问题。 对我有用的顺序是

AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);

之前是

AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register);

答案 19 :(得分:0)

尝试使用控制器名称的Value部分,如下所示:

http://localhost/api/Value

  

注意:按照惯例,路由引擎将获取作为控制器名称传递的值,并将单词Controller附加到其中。通过将ValueController放入URI中,您可以让路由引擎查找名为ValueControllerController的类,但它找不到它。