ASP.net MVC SPA路由

时间:2013-06-07 23:44:16

标签: asp.net-mvc asp.net-mvc-4 single-page-application

我打算用asp.net MVC4构建一个SPA,但由于路由,我不太确定如何设置我的项目。例如,大多数SPA使用像这样mypage/#/News/today的hashrouting。

如果我没有指定名为mypage/News/today Controller且行动News的{​​{1}},则直接浏览today会怎样?

应用程序应该处理两种类型的路由,我该如何实现?

我是否必须以经典的方式构建我的应用程序,例如使用适当的操作和视图添加多个控制器,还使用knockout,jquery等构建客户端MVC结构?

1 个答案:

答案 0 :(得分:0)

您必须让所有通往“页面”的路由都掉落,以让您的SPA处理它们(如果不是到达您的SPA中的真实页面,则包括假冒的404),但同时,需要确保您将获得正确的API调用和/或文件请求响应。

下面是我的设置(我正在使用Vue作为js框架,但这无关紧要,对于服务器端而言根本不重要)。

首先,除了默认的路由设置外,还将其添加到您的Startup.cs中:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        ...

        app.Use(async (context, next) =>
        {
            await next();

            var path = context.Request.Path.Value;
            // If there's no available file and the request doesn't contain an extension, we're probably trying to access a page
            if (context.Response.StatusCode == (int)HttpStatusCode.NotFound && !Path.HasExtension(path) && !path.StartsWith("/api"))
            {
                context.Request.Path = "/Home/SpaRedirect"; // attempts to redirect to the URL within the SPA
                context.Response.StatusCode = (int)HttpStatusCode.OK; // Make sure we update the status code, otherwise it returns 404
                await next();
            }
        });

        ...
    }

因此,新添加到HomeController的SpaRedirect如下所示,只是将请求的URL存储在ViewData中...

    public IActionResult SpaRedirect()
    {
        ViewData["RequestUrl"] = HttpContext.Request.Path;
        return View("Index");
    }

然后在Index.cshtml中,只需在会话存储中捕获请求的url,这样我们就可以在客户端使用它:

<script src="~/dist/main.js" asp-append-version="true">
    sessionStorage.setItem("redirectAttempt", @ViewData["RequestUrl"]);
</script>

然后在启动脚本文件(SPA的入口点)中,添加以下内容:

let redirectAttemptUrl = sessionStorage.getItem("redirectAttempt");
if (redirectAttemptUrl) {
    router.push(redirectAttemptUrl);
    sessionStorage.removeItem("redirectAttempt");
}

这只是检查是否存在所请求的URL,然后SPA的路由器尝试导航到该URL(在上面的示例中是一个vue-router),然后将其从存储中删除。

因此,如果用户尝试通过在URL栏中输入URL(或通过书签)直接导航到URL,则该应用将加载并放置到正确的位置(如果存在)。 。。。把我们带到最后一块...

最后,您必须在SPA中处理“ 404”,这是通过在您的route defs中添加一个包罗万象的路由来完成的,该路由将用户带到您设置的404组件页面,对于Vue来说,它如下所示:

// adding an explicit 404 path as well for programmatically handling when something is not found within the app, i.e. return this.$router.push('/404')
{ path: '/404', component: NotFound, name: '404', alias: '*' }, // remove alias to not show the actual url that resulted in our little 404 here
{ path: '*', redirect: '/404' }, // this is the catch-all path to take us to our 404 page

注意:我不是专家,所以可能会遗漏一些东西,希望对如何改进它有更多意见。这不能处理的一件事是,如果用户已经在SPA中并且由于某种原因直接编辑URL以导航到其他地方,它仍然会触发服务器调用和完全重载,理想情况下不会这样,但这是我要讲的一个很简单的问题。