ASP.NET MVC集成Angular 5页面刷新出现404错误求解决方案
解决Angular 5 + ASP.NET MVC页面刷新404问题
这个问题太常见了,本质是Angular的客户端路由和ASP.NET MVC的服务器端路由撞车了。当你刷新页面时,浏览器会直接向服务器请求当前URL(比如/user/detail/1),但你的MVC项目里根本没有对应这个路径的控制器和Action,服务器自然就返回404了。给你两个最常用的解决办法:
方法一:修改RouteConfig配置 fallback路由
这是本地开发和部署都通用的方案,让服务器把所有非API、非静态资源的请求都转发到Angular的入口页面(也就是你的Home/Index页面,因为你的_Layout.cshtml是在这里渲染的)。
- 打开项目里的
App_Start/RouteConfig.cs文件 - 调整路由顺序,把一个catch-all路由放在所有其他路由的最后,代码如下:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // 先保留你的API路由(如果项目里有API的话) routes.MapRoute( name: "Api", url: "api/{controller}/{action}/{id}", defaults: new { id = UrlParameter.Optional } ); // 再保留你原本的MVC页面路由(如果有的话) routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); // 最后加这个catch-all路由:所有匹配不到的请求都转到Home/Index routes.MapRoute( name: "AngularFallback", url: "{*url}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }
这样服务器会先匹配API、普通MVC页面的路由,只有当这些都匹配不到时,才会把请求转到Angular的入口页面,让Angular来处理客户端路由。
方法二:用IIS URL重写规则(适合部署到IIS的场景)
如果你的项目最终要部署到IIS上,也可以用URL重写模块来实现相同效果:
- 确保服务器安装了IIS URL重写模块(本地用IIS Express的话,VS一般已经自带了)
- 在项目的
Web.config里,找到<system.webServer>节点,添加下面的重写规则:
<system.webServer> <!-- 其他已有的配置 --> <rewrite> <rules> <rule name="AngularRoutes" stopProcessing="true"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <!-- 排除静态文件(比如js、css、图片) --> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <!-- 排除目录 --> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> <!-- 排除API路径,避免API请求被重写 --> <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" /> </conditions> <!-- 把所有符合条件的请求重写到根路径(Angular入口页面) --> <action type="Rewrite" url="/" /> </rule> </rules> </rewrite> </system.webServer>
这个规则会过滤掉静态文件、目录和API请求,剩下的所有请求都转发到Angular的入口页面,让Angular接管路由逻辑。
额外注意事项
- 你的_Layout.cshtml里的
<base href="/">设置是对的,这个不用改,它是Angular路由的基础路径。 - 如果有某些特定的MVC页面需要保留,一定要把这些路由放在catch-all路由(或者重写规则的排除项)前面,不然会被Angular接管。
内容的提问来源于stack exchange,提问作者Karan
相关产品推荐
相关产品推荐

