Developing Web Applications using ASP.NET 5 (beta 7) on Ubuntu Linux 14.04.2 LTS Part 4 – Understanding ASP.NET 5 Architecture

By: Nestor Guadarrama

 

In the previous article Developing Web Applications using ASP.NET 5 (beta 7) on Ubuntu Linux 14.04.2 LTS. Part 3 – Understanding DNX Architecture, I played around different concepts related to how .NET Execution Environment creates basic structures for support DNX projects (project.json). Also, we learnt how to use dnu and dnx utilities for retrieve packages, restore dependencies and compile ASP.NET 5 MVC projects. In this article, we will be working around what ASP.NET 5 projects basically needs for create more responsive web apps.

 

ASP.NET 5 ARCHITECTURE

 

When I wrote the basic project on the first article Developing Web Applications using ASP.NET 5 (beta 7) on Ubuntu Linux 14.04.2 LTS. Part 1 – Installing & Configuring, I used the basic structures for an ASP.NET 5 application running on .NET Core (basically I wrote code from scratch):

 

clip_image002

Figure 1. Basic structure for an ASP.NET 5 application

 

However, using other tools/utilities like Visual Studio 2015 or Yeoman, ASP.NET 5 create a new, very powerful, complete structures for these projects. I’ll assume that you already have experience working on Visual Studio. In the other hand, Yeoman is an open-source tool that works like a Visual Studio project template. The Yeoman command line tool yo works alongside a Yeoman generator. Generators define the technologies that go into a project.

 

clip_image004

Figure 2. Basic structure for an ASP.NET 5 application using Visual Studio 2015

 

clip_image006

Figure 3. Basic structure for an ASP.NET 5 application using Yeoman

 

Both projects were created using ASP.NET 5 MVC template offered for these tools. I’ll not discuss on this article how to create an ASP.NET 5 MVC project using Visual Studio in order to check its architecture. However, I’m more interested on compare files and directories structures created by Yeoman. Once you already have installed Yeoman on your environment, you can use its interface for create ASP.NET 5 MVC applications:

 

clip_image008

Figure 4. Using Yeoman for create an ASP.NET 5 MVC template

 

The Yeoman workflow is comprised of three core tools for improving your productivity and satisfaction when building a web app. These tools are:

 

· yo - the scaffolding tool from Yeoman

· A package manager, such as bower or npm.

· A build tool, such as Grunt or Gulp.

 

Once you select and name project for your ASP.NET 5 template, Yeoman will scaffold the project and its supporting files. In my case, I choose Web Application:

 

clip_image010

Figure 5. Project ASP .NET 5 MVC already set

 

The ASP.NET 5 Yeoman generator (generator-aspnet) uses Gulp out-of-the box. The ASP.NET generator creates supporting files to configure client-side build tools. A Grunt or Gulp task runner file is added to your project to automate build tasks for Web projects. The default generator creates gulpfile.js to run tasks. Running the generator with the --grunt argument generates Gruntfile.js:

 

yo aspnet --grunt

 

The generator also configures package.json to load Grunt or Gulp dependencies. It also adds bower.json and .bowerrc files to restore client-side packages using the Bower client-side package manager. In my case, I got Gulp configuration (out-of-the-box configuration):

 

clip_image012

Figure 6. Project settings and files created using Yeoman as scaffolding tool and Gulp as a build tool

 

Now, in order to test this new deployment, you should follow basic steps for execute your new ASP .NET 5 MVC using DNX:

 

clip_image014

Figure 7. Testing ASP.NET 5 MVC application created with Yeoman

 

Also, using Yeoman you can use Sub Generators on your ASP.NET 5 projects. You can add new generated files using Yeoman even after the project is created. Use sub generators to add any of the file types that make up your project. To demonstrate this, let’s add a new MVC controller and View for a new Admin page for the Web application. We’ll add the MVC controller first. When yo aspnet executes, it will add files to the current working directory, so you’ll want to cd into the correct directory before executing the commands. To add the MVC controller, execute the following command in the Controllers folder:

 

clip_image016

Figure 8. AdminController class created using Yeoman

 

The MvcController sub-generator is just one of many sub-generators available in yo aspnet. To see the full list of sub-generators, you can execute yo aspnet –help:

 

clip_image018

Figure 9. Sub Generatos listed by Yeoman

 

The sub-generators in yo aspnet are equivalent to the item templates in Visual Studio when you use File | Add New Item. To add a view, use the MvcView sub-generator. To add the Admin view, execute the following command from the Views/Admin folder: yo aspnet:MvcView Index. This code will create an index.cshtmlpage inside of this folder. I modified page for print “Administrator Page” as a title. This is the output:

 

clip_image020

Figure 10. Index.cshtml page created with Yeoman

 

Configuration layer

 

ASP.NET 5’s configuration system has been re-architected from previous versions of ASP.NET, which relied on System.Configuration and XML configuration files like web.config. The new configuration model provides streamlined access to key/value based settings that can be retrieved from a variety of sources. Applications and frameworks can then access configured settings using the new Options pattern.

To work with settings in your ASP.NET application, it is recommended that you only instantiate an instance of Configuration in your application’s Startup class. Then, use the Options pattern to access individual settings.

 

clip_image022

Figure 11. Sample that shows how to create a ConfigurationBuilder class and store key/value pairs on configuration structure

 

On the sample above, code is taking two (2) specific actions: a) Create an instance of ConfigurationBuilder object, which add structure for support configuration file sources using extension methods and b) Once ConfigurationBuilder invoked all sources available, then compile its own structure for create an instance of all configuration settings.

 

Information for ConfigurationBuilder instance was collected from a new configuration file named appsettings.json. Because the configuration framework has built-in support for JSON, XML, and INI configuration files, as well as support for in-memory configuration (directly setting values in code) and the ability to pull configuration from environment variables and command line parameters, now developers can use different approaches for set specific configuration settings on any place.

 

However, there is a caveat. The order in which configuration sources are specified is important, as this establishes the precedence with which settings will be applied if they exist in multiple locations. In the example above, if the same setting (Data:DefaultConnection:ConnectionString) exists in both appsettings.json and in an environment variable, the setting from the environment variable will be the one that is used. The last configuration source specified “wins” if a setting exists in more than one location. The ASP.NET team recommends specifying environment variables last, so that the local environment can override anything set in deployed configuration files.

 

As an example of what settings you can add into appsettings.json, next you will find content by default on Visual Studio ASP.NET 5 templates (the same template used for Yeoman creates the same file but empty, just brackets):

 

clip_image024

Figure 12. appsettings.json from an ASP.NET 5 project created using Visual Studio 2015

 

Also, following the same sample, you can noticed that ConfigurationBuilder is making calls to environment variables (env.EnvironmentName). ASP.NET 5 introduces improved support for controlling application behavior across multiple environments, such as development, staging, and production. Environment variables are used to indicate which environment the application is running in, allowing the app to be configured appropriately. We will talk more deeply about this topic on next articles.

 

WWWRoot folder

 

In previous versions of ASP.NET, the root of the project was typically the root of the web app. If you placed a Default.aspx file in the project root of an early version of ASP.NET, it would load if a request was made to the web application’s root. In later versions of ASP.NET, support for routing was added, making it possible to decouple the locations of files from their corresponding URLs (thus, HomeController in the Controllers folder is able to serve requests made to the root of the site, using a default route implementation).

 

However, this routing was used only for ASP.NET-specific application logic, not static files needed by the client to properly render the resulting page. Resources like images, script files, and stylesheets were generally still loaded based on their location within the file structure of the application, based off of the root of the project.

 

clip_image026

Figure 13. wwwroot folder created by Yeoman in Ubuntu

 

The file based approach presented several problems. First, protecting sensitive project files required framework-level protection of certain filenames or extensions, to prevent having things like web.config or global.asax served to a client in response to a request. Having to specifically block access (also known as blacklisting) to certain files is much less secure than granting access only to those files which should be accessible (also known as whitelisting). Typically, different versions were required for dev/test and production (for example web.config). Scripts would typically be referenced individually and in a readable format during development. It’s beneficial to deploy only production files to production, but handling these kinds of scenarios was difficult with the previous file structure.

 

The wwwroot folder represents the actual root of the web app when running on a web server. Static files, like appsettings.json, which are not located in wwwroot will never be accessible, and there is no need to create special rules to block access to sensitive files. Instead of blacklisting access to sensitive files, a more secure whitelist approach is taken whereby only those files in the wwwroot folder are accessible via web requests. Additionally, while the wwwroot folder is default web root folder, the specific web root folder can be configured in project.json.

 

Client Side Dependency Management

 

In a modern web application, there are several dependencies between external frameworks/utilities and your web application for managing client behaviors like pre-processing tasks, minification tasks, etc. ASP. NET 5 architecture takes advantage of these scenarios, adding different engines and frameworks for use directly in our web applications.

 

I already describe how Yeoman can help us to create ASP.NET 5 MVC projects (templates). Because there are an interesting list of these frameworks, I will not discuss this all of them. On next articles we will be having fun with some of them like Grunt and Gulp. For our main purpose, I’ll discuss here what I used for generating my ASP .NET 5 MVC project with Yeoman.

 

In Figure 8, we saw that Yeoman (using Gulp as a build tool) created several files for handle client dependencies. Particularly, I’m interested on structures created for managing all client dependencies like JavaScript components, CSS libraries, font libraries, etc. From documentation on ASP.NET, ASP.NET 5 MVC projects uses two (2) different package managers: Bower and NPM.

 

clip_image028

Figure 14. Bower and npm package configuration on an ASP.NET 5 project created with Visual Studio 2015

 

Bower is a “package manager for the web.” Bower lets you install and restore client-side packages, including JavaScript and CSS libraries. For example, with Bower you can install CSS files, fonts, client frameworks, and JavaScript libraries from external sources. Bower resolves dependencies and will automatically download and install all the packages you need. For example, if you configure Bower to load the Bootstrap package, the necessary jQuery package will automatically come along for the ride. You can compare Bower with Visual Studio NuGet.

 

NOTE: Visual Studio developers are already familiar with NuGet, so why not use NuGet instead of Bower? Mainly because Bower already has a rich ecosystem with over 34,000 packages in play; and, it integrates well with the Gulp and Grunt task runners.

 

In the other hand, npm makes it easy for JavaScript developers to share and reuse code, and it makes it easy to update the code that you're sharing.

 

In our Ubuntu ASP.NET 5 project, folder structures is a little different:

 

clip_image030

Figure 15. Folderstructure configuration on an ASP.NET 5 project created with Visual Studio 2015

 

On this project, we don’t see the formal structure folders for npm and/or Bower. Instead, there is main file named bower.json, which contains all required dependencies used/installed by bower. Also, because I created this project using Yeoman’s default settings (Gulp as a build tool), template created a file named gulpfile.json, which contains all references required by Gulp:

 

clip_image032

Figure 16. Bower.json and gulpfile.js files created by Yeoman ASP.NET 5 template

 

Client-side packages are listed in the bower.json file. The ASP.NET 5 Starter Web project pre-configures bower.json with jQuery, jQuery validation, and Bootstrap. If I want to add a new bower package, I can do it manually using bower commands. For testing purpose, I’ll add support for Chart.js package:

 

clip_image034

Figure 17. Chart.js package installed on ASP.NET 5 MCV project using Bower

 

Option –save update directly bower.json file for adding references to this new package and also creates internal structures and references inside project for using it:

 

clip_image036

Figure 18. Chart.js package installed project and bower.json file updated

 

Because I decided using bower command, on home/git/testasp5/wwwroot/lib folder, bower added the entire Chart.js package project, so I created a test page named testbarasp5.html inside of wwwroot for testing Chart.js (I used the bar sample posted here):

 

clip_image038

Figure 19. testbarasp5.html web page running Chart.js installed using bower

There are others client-side features like Bootstrap, Knokout.js and/or angular.js, but these feature are out of scope for this article.

 

This is it!. On next articles, I’ll be playing around with Logging features on ASP.NET. Also, we will start testing some of the frameworks that are ready for ASP.NET 5, like MVC 6 and EF 7.

 

 ‘till next time!