how work with angular 2 and mvc5 together?

时间:2017-07-30 11:46:18

标签: asp.net-mvc angular angular-ui-router angular2-routing

I have an mvc5 project working with angular. i implemented angular routing on my project and its working on without any problem

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router'
import { AppComponent } from './app.component';
import { AdminComponent } from './admin/admin.component'

@NgModule({
   imports: [BrowserModule, 
        RouterModule.forRoot([
        {
                path: 'admin',
                component: AdminComponent
        }
    ])
],
declarations: [AppComponent,AdminComponent],
bootstrap: [AppComponent]
})

now when i click on <a routerLink="/admin">Heroes</a> of my component template, my browser path will change to "localhost/Admin" and i see Admin component template, inside <router-outlet></router-outlet>! ok very good. but when i refreshed the browser or when i copy the current address and paste it in address bar...i saw HTTP 404. Error.. for solving this problem i created constrain for my RouteConfig !

i created this class:

     public class server_routes_constraint : IRouteConstraint
      {
        private readonly Func<Uri, bool> _per;

        public server_routes_constraint(Func<Uri, bool> per)
        {
          this._per = per;
        }
        bool IRouteConstraint.Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
          return this._per(httpContext.Request.Url);
        }
      }

and used it like t=what you see below in RoutConfig:

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

      routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{id}",
          defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
          constraints: new
          {
            serverRoute = new server_routes_constraint(url =>
            {
              return url.PathAndQuery.StartsWith("admin", StringComparison.InvariantCultureIgnoreCase);
            })
          }
      );

      routes.MapRoute(
        name: "angular",
        url: "{*url}",
        defaults: new { controller = "Home", action = "Index" }//
        );
    }

now every thing is working on and i can even refresh the page and use my angular route straightly. BUT!!!! :

my regular mvc routs not working! all of them will returning /home/index view.

Update: when i inserted this codes in my Route Config...All of Html.ActionLinks converts to html like this: <a href>Contact</a>!!! but in normal style they should be like this : <a href="/Home/Contact">Contact</a>

1 个答案:

答案 0 :(得分:0)

看起来,你已经完成了相反的配置。

查看RegisterRoutes方法中的注册路线。您将以admin开头的任何内容视为服务器端路由。其他任何内容都将重定向到/Home/Index

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

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                // Set a constraint to only use this for routes identified as server-side routes
                constraints: new
                {
                    serverRoute = new ServerRouteConstraint(url =>
                    {
                    var serverSideRoutes = new String[] { "Settings", "Dashboard", "About" }; //these are whitelisted serverside routes
                    return serverSideRoutes.Any(route => url.PathAndQuery.ToLowerInvariant().Contains(route.ToLowerInvariant()));
                    })
                }
            );

            // This is a catch-all for when no other routes matched. Let the Angular 2 router take care of it
            routes.MapRoute(
                name: "angular",
                url: "{*url}",
                defaults: new { controller = "Home", action = "Index" } // The view that bootstraps Angular 2
            );
        }
    }

使用此配置,路由引擎将检查您的路由是否包含serverSideRoutes中的任何一个。如果合格,它将重定向到服务器端页面,否则它将继续使用通配符angular

{*url}配置的下一个配置

例如。

如果您在浏览器中转到http://localhost:61189/Settingshttp://localhost:61189/Dashboard/Indexhttp://localhost:61189/About。所有这些路径都是合格的服务器端路由,路由引擎会将您重定向到受尊重的控制器/操作的razer页面。

如果您尝试访问serverSideRoutes中列出的任何其他路线,它将继续进行下一个配置并最终进入Angular配置。

希望能够消除困惑。