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):
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.
Figure 2. Basic structure for an ASP.NET 5 application using Visual Studio 2015
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:
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:
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):
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:
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:
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:
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.cshtml page inside of this folder. I modified page for print “Administrator Page” as a title. This is the output:
Figure 10. Index.cshtml page created with Yeoman
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.
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):
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.
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.
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.
Figure 14. Bower and npm package configuration on an ASP.NET 5 project created with Visual Studio 2015
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 our Ubuntu ASP.NET 5 project, folder structures is a little different:
Figure 15. Folder structure 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:
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:
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:
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):
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!