【问题标题】:ASP.NET MVC5 Application catch-all route being ignoredASP.NET MVC5 应用程序包罗万象的路由被忽略
【发布时间】:2016-06-23 16:15:18
【问题描述】:

我正在开发一个 Angular 2 spa,它将托管在 ASP.NET MVC 5 应用程序中。我希望每个请求都转到一条路线 - /home/index - 所以我删除了默认路线并将其替换为一个包罗万象的路线:

routes.MapRoute(
  name: "spa-catch-all",
  url: "{*anything}",
  defaults: new { controller = "Home", action = "Index" });

这是 RouteConfig.cs 文件中唯一的路由。

如果我在服务器 URL 之后没有任何路径值的情况下点击我的应用程序,如下所示:

http://myserver.org/

然后一切正常。如果我尝试访问这样的 URL:

http://myserver.org/sectionname

应用程序返回 404。

我已经安装了 Phil Haack 的 Route Debugger NuGet 包来尝试诊断此问题,并且调试器告诉我,我已删除的 asp.net 默认路由与我的 url 匹配。事实上,我什至没有看到包罗万象的路由,至少没有像我在调试器生成的“所有路由”表中定义的那样(它显示 {*catchall} 而不是 {*anything})。

MVC 似乎忽略了我的 RouteConfig 文件。

  • 有什么想法吗?
  • 我不认为默认路由是在 Web 应用程序本身之外的任何地方定义的。我需要清除我的路由表吗?
  • 在我对我的 RouteConfig 进行更改之前,是否可以从我的早期版本中缓存某些内容?

更新 1:

这是完整的 RouteConfig.cs 文件: public static void RegisterRoutes(RouteCollection 路由)

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

            routes.MapRoute(
                name: "spa-catch-all",
                url: "{*anything}",
                defaults: new { controller = "Home", action = "Index" });
        }
    }
}

我确实需要指出以下几点。

  • 此项目在 ASP.NET 4.6.1 下运行
  • 此项目中没有身份验证(在此项目之外处理)
  • 我在项目的任何地方都没有任何 OWIN 配置(没有 startup.cs、没有 startup.auth.cs 等)

更新 2:

无奈之下,我添加了两个新控制器来匹配默认路由 - 我们将它们称为“Path1”和“Path2” - 以匹配默认控制器 ({controller}/{action}/{ id}) 甚至不在 DARN ROUTECONFIG 文件中,但 MVC 仍然坚持匹配。这适用于我的基本情况(http://myapp/path1http://myapp/path2),但它仍然不适用于子路径(http://myapp/path1/subpath1)。

我几乎已经确定,要么我的路由配置被完全忽略(不知道为什么),要么我的路径中的 catch all 参数根本没有按预期工作。我在下面附上了 global.asax.cs 文件和 routeconfig.cs 文件(现在这样)。

using System;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;

namespace MyNamespace
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            RouteConfig.RegisterRoutes(RouteTable.Routes);            
        }
    }
}


using System.Web.Mvc;
using System.Web.Routing;

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

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

我没有想法,很想听听大家的建议。

更新 3:

出于进一步的绝望,我已经实现了一个自定义路由处理程序。我什至不在乎它在这一点上是否有效;我只是希望它在我发出请求时遇到断点。

我创建了一个名为“SpaRouteHandler”的非常简单的处理程序,它返回我的自定义 HttpHandler,创造性地称为 SpaHandler。 SpaHandler 目前什么都不做——它只是抛出一个异常。我只是想确认这该死的东西被击中了。

这是我的代码的最新版本:

using System;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;

namespace MyNamespace
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            RouteConfig.RegisterRoutes(RouteTable.Routes);            
        }
    }
}



using System.Web.Mvc;
using System.Web.Routing;

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

            RouteValueDictionary defaults = new RouteValueDictionary {{"controller", "Home"}, {"action", "Index"}};
            var customRoute = new Route("{*.}", defaults, new SpaRouteHandler());
            routes.Add(customRoute);
        }
    }
}



using System.Web;
using System.Web.Routing;

namespace MyNamespace
{
    public class SpaRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new SpaHandler(requestContext);
        }
    }
}



using System;
using System.Net;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MyNamespace
{
    public class SpaHandler : IHttpHandler
    {
        public RequestContext LocalRequestContext { get; set; }

        public SpaHandler(RequestContext requestContext)
        {
            LocalRequestContext = requestContext;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public void ProcessRequest(HttpContext context)
        {
            throw new NotImplementedException("Just throw an error please");
        }
    }
}

异常永远不会被击中。良好的旧默认路由 - 配置中不存在 - 似乎仍然有效。

我到底做错了什么?!?!?!?!?

【问题讨论】:

  • 显示你的RouteConfig.cs文件
  • 我会在上面添加。

标签: angular asp.net-mvc-5 routing angular2-routing


【解决方案1】:

事实证明,这很奇怪。我从最初创建项目时更改了 Web 应用程序的命名空间,并使用 ReSharper 的调整命名空间重构工具来调整整个项目的命名空间。但是,无论出于何种原因,它都没有更改 global.asax 文件中 <Application /> 标记的 Inherits="" 属性中的命名空间引用。它引用的是旧版本的 DLL,所以我的 Application_Start 甚至没有被调用。

一旦我更改了该引用,一切都开始按计划进行。

【讨论】:

    【解决方案2】:

    试试这个:

      app.UseMvc(routes =>
        {
            routes.MapRoute(name:"default", template:"{controller=Default}/{action=Index}/{id?}");
    
            routes.MapRoute("CatchAll", "{*url}", new {controller = "Default", action = "Index"});
        });
    

    【讨论】:

    • 此解决方案适用于 MVC 5 还是 ASP.NET Core MVC?
    • 另外,我不需要那里的默认路由。就我而言,我的包罗万象是默认路线。
    • 这段代码会去哪里?全球.asax.cs? RouteConfig.cs(在 App_Start 下)?
    • 你只能复制路线,但是通常在Startup.cs
    • 我很确定您的解决方案适用于 ASP.NET 5 (MVC 6)。 startup.cs 中的 app 对象在 MVC 5 中没有“UseMvc”方法,否则我的配置中有一些非常糟糕的东西,因为我没有看到它。
    猜你喜欢
    • 2016-08-20
    • 2011-04-02
    • 2011-10-13
    • 2016-02-22
    • 2011-04-27
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多