Visual Studio 单页应用程序集成

10

技术:

  • Visual Studio 2017
  • Asp.Net Core Tooling 1.1
  • .Net Framework 4.6.2

单页应用程序及其与Visual Studio的集成变得更加容易,因为Visual Studio内置了许多新的支持。但是本周早些时候,Jeffery T. Fritz发布了一篇非常好的文章,介绍了使用以下软件包进行集成和实现:

  • Microsoft.AspNetCore.SpaServices
  • Microsoft.AspNetCore.NodeServices

在查看了几个模板并进行分析后,您会注意到在解决方案资源管理器中有一个名为ClientApp的目录。这是通过Webpack配置和路由。

问题出现在Startup.cs文件中。

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
            {
                HotModuleReplacement = true
            });
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

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

            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new { controller = "Home", action = "Index" });
        });
    }

在我们的请求中,有一些路由到我们的MVC框架。

问题是,为什么我们需要指定这个路由? 如果我们只使用 app.UseDefaultFiles()app.UseStaticFiles(),并在我们的wwwroot中指定我们的索引。 我们的客户端路由器将始终返回。 那么为什么我们不这样做:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
            {
                HotModuleReplacement = true
            });
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseDefaultFiles();
        app.UseStaticFiles();
    }

我知道我们wwwroot中直接的项目不会被压缩,也可能泄露安全性,但除了这两个缺点之外,为什么不使用这种方法来确保你的主页和客户端路由器不总是返回呢?

我的问题具体是关于强制MVC始终返回Home/IndexUseDefaultFiles()/ UseStaticFiles()的概念。 我错过了什么,为什么我们要强制MVC返回它?

重要提示:基本上,问题的核心是如何强制返回主页,使得我们的客户端路由器来处理更改,而不是后端返回特定的视图状态。


他的名字是“Jeffrey”,文章链接为:https://blogs.msdn.microsoft.com/webdev/2017/02/14/building-single-page-applications-on-asp-net-core-with-javascriptservices/。 - John Pankowicz
2个回答

4
这些 SPA 模板都使用最小的 ASP.NET Core MVC 服务器基础。我们需要 MVC 的默认路由从 Index.cshtml 生成 html 标记。
我没有看到模板的 wwwroot / dist 文件夹中生成任何普通的 html 文件。所以 app.UserDefaultFiles() 没有 Index.html 可供访问。
我可以推测,也许 mvc 路由也在那里,以防有人决定为多页面 SPA 应用程序(矛盾之词)合并更多的控制器/操作/视图;或者开始使用后端 web api...?
我对 MapSpaFallbackRoute 不太熟悉,但它作为某些路由未被 SPA 覆盖的全局匹配项。请参见源代码: https://github.com/aspnet/JavaScriptServices/blob/dev/src/Microsoft.AspNetCore.SpaServices/Routing/SpaRouteExtensions.cs 为了全面一些,让我们提到,如果我们想要无服务器、仅静态文件、从 CDN 提供服务,还有起始模板和一个 Angular CLI:

https://github.com/AngularClass/angular2-webpack-starter

https://github.com/angular/angular2-seed

https://cli.angular.io/

但是,如果这些静态/无MVC的Javascript应用程序托管在IIS中,它们将需要一个具有最小路由设置的web.config。请参见:

https://github.com/angular/angular/issues/11046

编辑:

另一个原因可能是许多人将在这些项目中使用 Web API,因此我们仍需要使用 app.UseMvc();


但是如果你存储了一个静态索引,或者默认情况下它会搜索并返回。根据文档,它的顺序是异常、静态、授权、MVC。中间件可以在更早的时候检测到并退出。这不是真的吗?但是你不需要在IIS上托管.NET Core。 - Greg
index.html将会手动创建,用于返回静态页面。 - Greg
您可能会遇到页面刷新问题(即深度链接);如果没有某种路由机制指向 index.html 页面,可能会收到 404 错误。 - travis.js
如果是静态的,但是例如vue.js路由器和vuex数据存储应该持有它。 - Greg
同时,您可以在没有web.config的情况下托管Angular 2,您可以使用URL Rewrite,因此对于这个问题,有几个概念上的观念似乎被错误地描述了。 - Greg

3

这似乎是我们之前见过的所有东西,只是更好地打包了起来。

    // allow returning of physical files on the file system of the web root and it's sub dirs
    app.UseDefaultFiles();
    app.UseStaticFiles();

    // map MVC routes to controller actions when a static file cannot be found
    app.UseMvc(routes =>
    {
       // default routing convention for mapping "most situations"
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");

        // fallback routing 
        routes.MapSpaFallbackRoute(
            name: "spa-fallback",
            defaults: new { controller = "Home", action = "Index" });
    });

根据评论所述...

如果静态文件不存在,它确实是一个备选项。但是,如果在wwwroot中包含index.htm,则在不传递特定头信息的情况下,它从技术上讲永远不会执行该路由。


我喜欢你的回答,因此实质上它确实是一个备选方案,如果静态文件不存在。但是,如果在wwwroot中包含index.htm,除非传递特定的标头信息,否则技术上永远不会执行该路由。能否请您修改以反映这一点? - Greg
好的,我们开始吧 :) - War
谢谢。不幸的是,您下面的答案中有很多错误信息。 - Greg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接