MVC route 和 Angular router 单页面的一些方式

直接看代码和注释吧

ASP.NET MVC router

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("favicon.ico");
        routes.MapMvcAttributeRoutes();  //一定要在 routes.MapRoute 之前注册 
        //单页面的处理
        routes.MapRoute(
            name: "PersonalProfile",
            url: "personal-profile/{*pathInfo}", //这样写可以把所有under personal-profile 的路径连到同一个控制器
            defaults: new { controller = "PersonalProfile", action = "Index", pathInfo = "pathInfo" }
        );
        //一般的处理
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );            
    }
}

ASP.NET Controller

//[RoutePrefix("personal-profile")]
public class PersonalProfileController : Controller
{        
    //[Route("")]
    public ActionResult Index(string pathInfo)
    {
        //pathInfo 我们还可以另作处理
        return View();
    }
}

这里可以注意一点,如果使用了 AttributeRoute , routeMap 就不灵了,

cshtml Angular

@{
    Layout = null;
}

<!DOCTYPE html>

<html ng-app="app" ng-controller="ctrl">
<head>
    <base href="http://localhost:58404/personal-profile/" />
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    personal profile
    <script src="~/js/jquery.js"></script>
    <script src="~/js/angular.js"></script>
    <script>
        function redirectBaseUrlWithoutSlash() {
            //refer : https://github.com/angular/angular.js/issues/14018

            if (location.pathname.charAt(location.pathname.length - 1) != "/") {
                var oldHref = location.href;
                var newHref = location.protocol + "//" + location.host + location.pathname + "/" + location.search + location.hash;
                console.log(oldHref);
                console.log(newHref)
                location.href = newHref;
            }
        }
        redirectBaseUrlWithoutSlash(); //处理没有url来的时候不是end with /

        var app = angular.module("app", []);
        app.config(["$locationProvider", function ($locationProvider) {
            //note :
            //因为 angular 在做 $location 和 <base> 的时候会对比游览器的url
            //而且是有区分大小写的,所以很容易error
            //reset之后就不会有这个问题了.
            //做法是拿游览器的url replace 进 base href

            var wholeUrl = location.href;
            var baseElem = document.getElementsByTagName("base")[0];
            var baseUrl = baseElem.href;
            var newBaseUrl = wholeUrl.substring(0, baseUrl.length);
            baseElem.href = newBaseUrl;

            $locationProvider.html5Mode({
                enabled: true,
                requireBase: true
            });
        }]);
        app.controller("ctrl", ["$location", function ($location) {
            console.log("start");
        }]);
    </script>
</body>
</html>

注意 angular 和 base 的冲突