混合SPA和ASP.NET MVC路由

时间:2018-02-14 17:27:47

标签: c# asp.net-mvc angular asp.net-core asp.net-core-mvc

我正在开发混合路由Angular 2和ASP.NET Core 2(razor)项目。你会如何跳出角度路由并获得剃刀页面?我尝试使用角度路由捕获所有未知路由并重新加载未知路由但是如果有路径,ASP.NET和angular不会识别它进入循环。 Configure类的Startup方法包含此方法。

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";
    });
}

一些例子:

  • Mvc route Mysite.com/documents/view/
  • Angular route Mysite.com/PendingTransactions

1 个答案:

答案 0 :(得分:1)

解决方案适用于MVC 4.

注意:您应该在所有其他路线之后,但在捕获所有路线之前放置默认路线。

从MVC路由中排除Angular应用程序(您会注意到有关真/假评估的一些有趣内容,这是因为应用程序路由由MVC处理,除非我们在/ app angular应用程序中。您可以看到相反的植入{{ 3}}):

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;
                    })
                }
            );

ServerRouteConstraint类:

 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);
        }
    }

当没有其他路线匹配时,这是一个全能。让Angular路由器处理它

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