6
votes

I'm working on a mixed routing Angular 2 and ASP.NET Core 2 (razor) project. How would you jump out of angular routing and get razor pages? I tried catching all unknown route with angular routing and reloading the unknown route but if there is a route ASP.NET and angular doesn't recognize it goes into a loop. The Configure method of the Startup class contains this.

public void Configure(IApplicationBuilder app)
{
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "Index",
            defaults: new { controller = "controller", action = "Index" },
            template: "{controller}");

        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");

        routes.MapRoute(
            name: "Login",
            defaults: new { controller = "Sessions", action = "New" },
            template: "Login");
    });

    app.UseSpa(spa =>
    {
        // To learn more about options for serving an Angular SPA from ASP.NET Core,
        // see https://go.microsoft.com/fwlink/?linkid=864501

        spa.Options.SourcePath = "ClientApp";
    });
}

Some examples:

  • Mvc route Mysite.com/documents/view/
  • Angular route Mysite.com/PendingTransactions
1
If you down vote a question have the decency to point out why. - Ben Weidberg
Do you have the angular app and the mvc app sharing some common routing. ie mysite.com/app/angular and mysite.com/app/mvc? Please give some examples of the routes in your app and the configuration you have for MVC and Angular for those routes. - Zzz
Just noticed that you are using ASP.Net Core MVC. I have solved this issue in ASP.Net MVC (NOT Core) with angular 5. Let me know if you would like for me to answer this question with what worked for me, but you will have to apply it to Core on your own. - Zzz
I would like you (Zzz) answer the question for asp.net mvc and I'll try to port it to core. - Ben Weidberg
Did my answer help? - Zzz

1 Answers

1
votes

Solution works for MVC 4.

NOTE: You should place your default route after all your other routes, but before your catch all route.

Exclude Angular app from MVC routing (You will notice something funny with the true/false evaluation, this is because the app routing is handled by MVC unless we are in the /app angular application. You can see the opposite implantation here):

routes.MapRouteLowercase(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                constraints: new
                {
                    serverRoute = new ServerRouteConstraint(url =>
                    {
                        var isAngularApp = false;
                        if (url.PathAndQuery.StartsWith("/app",
                            StringComparison.InvariantCultureIgnoreCase))
                        {
                            isAngularApp = true;
                        }               
                        return !isAngularApp;
                    })
                }
            );

The ServerRouteConstraint class:

 public class ServerRouteConstraint : IRouteConstraint
    {
        private readonly Func<Uri, bool> _predicate;

        public ServerRouteConstraint(Func<Uri, bool> predicate)
        {
            this._predicate = predicate;
        }

        public bool Match(HttpContextBase httpContext, Route route, string parameterName,
            RouteValueDictionary values, RouteDirection routeDirection)
        {
            return this._predicate(httpContext.Request.Url);
        }
    }

This is a catch-all for when no other routes matched. Let the Angular router take care of it

    routes.MapRouteLowercase(
        name: "angular",
        url: "{*url}",
        defaults: new { controller = "App", action = "Index" } // The view that bootstraps Angular 5
    );