Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio Single Page Application Integration

Technology:

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

Single Page Application's and their integration into Visual Studio have become easier, with all the new support built into Visual Studio. But earlier in the week, Jeffery T. Fritz released a really nice article on the integration and implementing with the following packages:

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

After you go through and even analyze a couple of the templates, you'll notice in your Solution Explorer, a directory called ClientApp. This is configured, and routed via Webpack.

Inside the Startup.cs is where the issue reveals itself.

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

Inside our request, we have some routing to our MVC Framework.

The question, why do we need to specify this route? If we simply utilize the app.UseDefaultFiles() and app.UseStaticFiles() and have our index specified in our wwwroot. Our client side router will always be returned. So why do we not do it this way:

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

I understand that items directly in our wwwroot aren't compressed, also can leak security, but aside from those two drawbacks why not use this route to ensure your index and client side router aren't always returned?

I'm specifically asking about the concept of forcing MVC to always return a Home/Index or UseDefaultFiles() / UseStaticFiles(). What am I missing, why are we being told to force MVC to return it?

Important: Basically the issue targeted, is how to force the index to be returned so our client side framework's router is handling the changes vs the backend returning a specific view state.

like image 962
Greg Avatar asked Feb 24 '17 00:02

Greg


People also ask

Can we create single-page application using MVC?

Yes You could. There are numerous approaches to this kind of task, I will name two of them. The MVC approach is as follows: You will have one controller that will contain all your input logic and action results.

What is best for single-page application?

You'll easily recognize some popular examples of single page applications like Gmail, Google Maps, Airbnb, Netflix, Pinterest, Paypal, and many more. Companies all over the internet are using SPAs to build a fluid, scalable experience.

Is ASP Net SPA?

ASP.NET - Single-Page Applications: Build Modern, Responsive Web Apps with ASP.NET. Single-Page Applications (SPAs) are Web apps that load a single HTML page and dynamically update that page as the user interacts with the app.

What is SPA in .NET Core?

A Single Page Application (SPA) is a popular type of web application due to its inherent rich user experience. Integrating client-side SPA frameworks or libraries, such as Angular or React, with server-side frameworks such as ASP.NET Core can be difficult.


2 Answers

These SPA templates all use a minimal ASP.NET Core MVC server foundation. We need the default route for MVC to generate the html markup from Index.cshtml.

I don't see any plain html files being generated in the template's wwwroot/dist folder. So app.UserDefaultFiles() has no Index.html to go to.

I could speculate that maybe the mvc routes are there also in case someone decides to incorporate more controllers/actions/view for a multi-page SPA application (oxy-moron); or to get started with the back end wep api...?

I'm not as familiar with MapSpaFallbackRoute, but it serves as a catch-all, or catch-some, for certain routes not covered by the SPA. See source code: https://github.com/aspnet/JavaScriptServices/blob/dev/src/Microsoft.AspNetCore.SpaServices/Routing/SpaRouteExtensions.cs

Just to be holistic, let's mention that if we want to be server-less, static-file-only, serve-it-from-a-CDN- there are starter templates and an angular cli to boot:

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

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

https://cli.angular.io/

But, if these static/mvc-less Javascript apps are hosting in IIS, they will need a web.config with minimal routing setup. See:

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

EDIT:

Another reason might be that many people would be utilizing the web api in these projects, and for that we would still need to app.UseMvc();

like image 189
travis.js Avatar answered Oct 17 '22 08:10

travis.js


It seems to be all stuff we have seen before just more nicely packaged up.

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

As per comments ...

It really is a fallback should a static file not exist. But, if it does contain a index.htm in the wwwroot, it would technically never execute that route unless particular header info is passed

like image 28
War Avatar answered Oct 17 '22 07:10

War