ASP.NET 5 + Angular 2 routing (template page not REloading) ASP.NET 5 + Angular 2 routing (template page not REloading) angular angular

ASP.NET 5 + Angular 2 routing (template page not REloading)


The problem you're seeing has to do with the difference between Angular routing on the client and MVC server-side routing. You are actually getting a 404 Page Not Found error because the server does not have a Controller and Action for that route. I suspect you are not handling errors which is why it appears as if nothing happens.

When you reload http://localhost:5000/aboutus or if you were to try to link to that URL directly from a shortcut or by typing it into the address bar (deep linking), it sends a request to the server. ASP.NET MVC will try to resolve that route and in your case it will try to load the aboutusController and run the Index action. Of course, that's not what you want, because your aboutus route is an Angular component.

What you should do is create a way for the ASP.NET MVC router to pass URLs that should be resolved by Angular back to the client.

In your Startup.cs file, in the Configure() method, add an "spa-fallback" route to the existing routes:

app.UseMvc(routes =>{    routes.MapRoute(        name: "default",        template: "{controller=Home}/{action=Index}/{id?}");    // when the user types in a link handled by client side routing to the address bar     // or refreshes the page, that triggers the server routing. The server should pass     // that onto the client, so Angular can handle the route    routes.MapRoute(        name: "spa-fallback",        template: "{*url}",        defaults: new { controller = "Home", action = "Index" }    );});

By creating a catch-all route that points to the Controller and View that ultimately loads your Angular app, this will allow URLs that the server does not handle to be passed onto the client for proper routing.


In your Startup.cs add this to the Configure method. This must be before other app statements.

app.Use(async (context, next) => {    await next();    if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value)) {        context.Request.Path = "/index.html"; // Put your Angular root page here         await next();    }});


My favorite solution is to add the following code to Global.asax.cs which very smoothly and reliably takes care of the issue:

     private const string RootUrl = "~/Home/Index";     // You can replace "~Home/Index" with whatever holds your app selector (<my-app></my-app>)     // such as RootUrl="index.html" or any controller action or browsable route     protected void Application_BeginRequest(Object sender, EventArgs e)        {            // Gets incoming request path            var path = Request.Url.AbsolutePath;            // To allow access to api via url during testing (if you're using api controllers) - you may want to remove this in production unless you wish to grant direct access to api calls from client...            var isApi = path.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase);            // To allow access to my .net MVCController for login            var isAccount = path.StartsWith("/account", StringComparison.InvariantCultureIgnoreCase);            if (isApi || isAccount)            {                return;            }            // Redirects to the RootUrl you specified above if the server can't find anything else            if (!System.IO.File.Exists(Context.Server.MapPath(path)))                Context.RewritePath(RootUrl);        }