ASP.NET Core : Building Enterprise Solutions
Introduction & Background
When a person begins a career in software development she knows that she must learn how to write code to create software solutions. Immediately, the creation of code becomes the primary thing. Slowly but surely she falls in love with the code itself as she learns more details of how the language and the computer work to create her software solutions. At times she may write code that she knows is so elegant that it transforms before her eyes into “A Thing of Art”.
However, at some point, a change occurs. The change probably begins with pain. The service has crashed in production at 2am and she is forced to wake up and get things working. Customers begin lighting up the phones, yelling at support. Customer support demands to know when the patch will be applied. Other members of the development team are contacted by support. The development manager is awakened.
Finally, all the noise makes its way up to C-Suite executives.
“Production is down and it was Software Developer’s bad code that caused this issue.”
Meanwhile the developer is trying to debug the production code as email, phone calls, instant messages, and text messages bombard her, asking when the resolution will be deployed.
This is how everything changes for the software developer. Code is no longer that beautiful thing a software developer sits with and knits together while sipping coffee.
Code Is A Warm Puppy (And An Evil Hound)
Sure, during the day code is a warm puppy, innocent and safe, but at night it transmogrifies into Cerberus (three-headed dog from Greek mythology) which devours the software developer, all her confidence, and her best intentions.
Quote:
Some people change when they see the light, others only when they feel the heat.
That is when the light flashes on for the developer: “Software must be made more simple. Code must be easy to debug. There must be some organization to the code. Testing must be automated. There must be easier ways to deploy a hotfix to production.”
That is the moment when the Software Developer becomes a System Architect in her heart.
She cries out, “There must be a process to tame this dangerous beast!”
However, there is much to learn but only little helpful guidance about where to start and which direction to go in.
Isn’t ASP.NET Core Just a New Coding Technology?
What does this story have to do with ASP.Net Core?
Not Just Web Pages Or Coding Language
The new ASP.NET Core is not just a new language a software developer uses to create web pages.
Entire System To Create Development Process
Instead, it is intended to be an entire system created as a way to wrap a process around building enterprise software.
Understanding that difference (and being interested in what that difference means) will go a long way toward moving us closer to obtaining the right view of developing Enterprise Systems.
Robert C. Martin summarizes it in the following way:
Robert C. Martin:
“The goal of software architecture is to minimize the human resources required to build and maintain the required system.” from : Clean Architecture: A Craftsman's Guide to Software Structure and Design
What Does That Mean To This Book?
It means that we will not just focus on writing code. We will definitely learn the details of writing code but I will always attempt to place it in a context of creating Enterprise Solutions.
Aren’t Enterprise Systems Only For Huge Corporations?
Enterprise systems really mean any system that have real customers depending upon them. That means even if you’re an Indie Developer you need solid code built within a recreatable process that allows you to manage your code, deployment and support. As a matter of fact, since you may represent the entire IT team you have to depend upon a process which will insure the stability of your system.
The How & The Why
So, instead of picking up this book and just learning how to write code which will do certain things, we will also look at why we would prefer one way over another.
Microsoft’s creation of ASP.NET Core is an attempt to push and guide developers into specific ways of doing things but at times there is little explanation of why they have pushed towards certain technologies. This can be confusing to newer developers so we will talk about the trade-offs that Microsoft has chosen and what tools they’ve provided to nudge developers toward their process.
What Will You Learn In This Book?
I want to investigate dotnet core quite thoroughly so I want to create some complete solutions.
At first (along with the word Enterprise in the title of this book) it may sound like I’m talking about writing huge systems, but I am not.
I want to show how ASP.NET Core can be used to create a complete system such as a blogging software (CMS - Content Management Service), a bug tracking system, a customer contact system, etc.
But I’d also like to show how to create small solutions that can be used in large Enterprises : think Microservices.
Finally, I’d like to show how you can write code that runs independently and yet can easily be integrated to manage your Enterprise data.
Enterprise Solution Means Many Things
All of this means you could be an Indie Developer who is building his own blogging software for use in a startup company. Or, you can be a Software Architect who wants to leverage the power of ASP.NET Core to build a small service which will integrate with currently running systems.
What Types of Things Will This Drive Us To Learn?
I believe thinking in this way will allow us to build a number of systems which will move us through many subjects like:
- Designing Data Stores (nosql, Microsoft Sql Server, etc. - whatever is appropriate)
- Version Control (using Git to track our changes) - all code from this book will be available via GitHub.
- OOD/P Concepts (Object Oriented Design and Programming concepts for code organization - following SOLID principles, etc)
- Refactoring (finding common functionality and moving it to easily referenced / usable libraries)
- Nuget (making our libraries easily available to other projects : makes us able to leverage the work we’ve already done, making us able to develop projects more quickly)
- Unit Testing (insuring our libraries continue to work as changes are applied)
- Security Issues: how do we make our apps functional while still protecting our data and user’s data.
Some Items We Will Focus On
How to build a ASP.NET Razor Pages solutions which include the MVC framework.
How to build Web APIs to make functionality more easily shared between your Enterprise solutions (this is integration)
Instant Update Solutions : We will also look at SignalR (and possibly Firebase) as solutions which allow instant update to users who are online and viewing an app or web page (like twitter or chat app)
Deploying ASP.Net Web solutions and Web API solutions to Windows and Linux. For indie devs specifically, the fact that you can now develop .NET-based solutions and then deploy them to inexpensive Linux containers is a huge win.
Technology-Specific Things We’ll Learn
Since a ASP.NET Core application contains numerous technologies there will be a lot to learn, but we’ll take it in pieces so it doesn’t overwhelm us.
Here’s a list of some of the more obvious technologies we will learn:
HTML, JavaScript, C#, Razor view engine, MVC (Model, View, Controller and how they are implemented in Core), BootStrap, CSS, Sql Server (LocalDB / Sql Express) and many more.
Specific Software Solutions We’ll Write
-
New Social Media app. You will see how to build a new social media app which allows you to post your content as a way to keep track of things you find as you research or search the Internet. Your posts are private by default but you can make them visible to others on your feed. You can also follow other people’s feeds. This is an interesting thing to solve since it has many pieces of functionality which are challenging to create.
-
Basic web-based customer contact system
-
Basic web-based bug tracking system
-
Integration of previous apps - these will allow us to see how we might share data between this apps
Feasibility Study
I am often wondering whether or not I could choose the proper technology stack to build an entire Enterprise System on : ie, does such a thing exist? That is the additional thing I am interested in investigating in this book: Is it feasible to build an entire Enterprise System on Microsoft ASP.NET Core and will it all be stable?
An Enormous Undertaking
I understand that I’ve set out a huge task for us and for this book, but it is not because I believe I’m some kind of genius Software Architect who builds Enterprise Software with mere keystrokes. It’s because I like to set extreme goals for myself in an attempt to push myself and see if I can get to an amazing goal. On my way there I do, at times, discover that you can’t get there from here and I am often forced down side paths. However, I gain large chunks of experience while on the journey and that is what is important.
Getting Started
Admittedly this is a lot of work to do. However, we will jump in at the very basic level of building our first ASP.NET Core web app and build from there. I will do my best to set you on a strong foundation and then work with you to build on it. I will do my best to make sure you understand the basics so we can move through building these larger solutions and systems all while understanding what exactly is going on and why we are choosing certain paths.
If this sounds interesting to you let’s start the journey in our first chapter where we will start writing and running our first dotnet core code.
Chapter 1
I always like to start right at the beginning with my books so I will often walk my readers through the installation of our development tools. However, there are a few reasons I’m not going to show you the Visual Studio 2017 walk-thru in this book:
-
I’m assuming that you have at least enough experience to walk through getting and installing Visual Studio 2017 (Community edition) yourself.
-
The Visual Studio 2017 provides a simple wizard that even a beginner can most likely get through without help.
-
I’ve already documented Visual Studio 2017 installation in my previous book, Programming Windows 10 and you can see the basics at: https://www.codeproject.com/Articles/1215695/Programming-Windows-UWP-Focus-of-N
-
Note: there’s just one additional package to choose in the installer (shown below*).
-
I want to get started writing code
Here are all the packages that you should choose when installing Visual Studio 2017. *The [ASP.NET and web development] item is not chosen if you read the previously mentioned online document but is necessary for our work in this book.
At this point, I assume you’ve installed Visual Studio 2017 (and all the packages shown in the previous screen shot) and your system is set up properly and ready to go.
Test DotNet Installation
The first thing you can do to test that your installation went properly is :
-
Open a command prompt
-
Type the following:
dotnet --version<ENTER>
You should see something like the following:
You should have version 2.0.2 or later of the dotnet core.
Once you’ve confirmed that you do have dotnet core installed we are ready to build our first app. If you haven’t seen how easy (and somewhat ridiculous) this is with the latest Microsoft technologies then the next few steps are probably going to be a bit amazing. The first time I saw this, it was to me.
First Project From Command Line
We’re going to build a complete ASP.NET Core app from a template on the command line.
Create Directory
First thing you should do is create a new directory to put the project in.
If you are in your user directory as I am, just go ahead and execute the following command:
c:\>users\<username>>md FirstDN<ENTER>
Next, change directory to that directory so when we run our command the files will be created in that subdirectory.
c:\>users\<username>>cd firstdn<ENTER>
If you’ve done all of that properly then it will look like the following:
Here comes the magic.
Type the following command:
c:\>users\<username>>dotnet new razor -o FirstDN<ENTER>
When you do that, you are telling the dotnet to create a new Razor-based web application named (-o for output) FirstDN.
Dotnet has created a new directory named FirstDN under our current directory and it has created all of the files in that and other subdirectories it has created. After it created the project it connected to Nuget (package manager) pulled required libraries (DLLs) into the project. It has also generated the required MSBuild (Microsoft’s build system) files that the system needs to build the final project.
Let’s change directory into new one that dotnet created.
c:\>users\<username>\FirstDN>cd firstdn<ENTER>
I’ve executed the dir command to show you the list of files that the project contains.
You can see there are some .cs
files (CSharp files contain code) a few json (JavaScript Object Notation) files and a csproj
(CSharp project) file in here. There are also some subdirectories and we’ll learn all about what is contained in those later. The important ones are the Pages
subdirectory and the wwwroot subdirectory. The Pages subdir contains actual web pages that will be rendered to the user. The wwwroot
subdir allows this web app to be hosted directly from this directory when we start the app up.
Now, all we have to do is call the command to build and start the app. It’s amazingly simple.
All you have to do is run the dotnet run command.
C:\Users\<username>\FirstDN\FirstDN>dotnet run<ENTER>
When you do the msbuild system will kick in and build the app and then start up a local web server running on port 5000 (by default).
At this point, the app is running and you can point your web browser at the URL (http://localhost:5000) and the web site will be rendered for you.
Razor Pages Project
The thing you have just created is called a Razor Pages project. It is extremely similar to ASP.NET MVC 5 project and it is built on top of ASP.NET MVC, but it is a different animal.
We will discuss the differences and see how you create a Razor Pages Project versus a MVC project using Visual Studio as we move through the content.
So we can get a better idea of what is in this project, let’s open it up in Visual Studio.
Open Project In Visual Studio
You can just start Visual Studio, do a File…Open → Project/Solution… and then navigate to the csproj file (c:\users\<username>\FirstDN\FirstDN\
)
Finally, just double-click on the FirstDN.csproj
file.
Visual Studio will load the project and display the project structure in the Solution Explorer (usually found on the right side of Visual Studio). However, no files are opened so Visual Studio looks a bit blank at this point.
As I’ve mentioned before (in my previous book, Programming Windows 10 Via UWP) there’s a lot in Visual Studio and your eyes kind of wander around trying to determine what is important. For now there are three main areas to initially focus on shown in the next image.
1 -- The Toolbox is not as important when developing a web app since we often type the HTML ourselves but there are times when we will drop a control on a Web Form and it will show up in the toolbox.
2 -- The next thing to take note of is the main menu. Everything you need to get to is located somewhere in this menu.
3 -- Finally, when a project loads up, there is a always more than one file and folder associated with the project and all those files are called our Solution. The Solution Explorer on the right side is populated with a treeview that will show us the folders and files that are included in our project.
Taking Inventory On Everything DotNet Core Has Done
Let’s take a look at everything that is in Solution Explorer so we can begin to get oriented on what dotnet core has done for us.
Opinionated Development / Opinionated Architecture
There’s a lot here that dotnet has done for us and that can feel quite overwhelming since it is almost magically created an entire web site with JavaScript, Bootstrap, jQuery, Razor Pages and C# code simply by running a few lines at the command line.
That is the point of my original introduction. Microsoft is attempting to create a framework which provides a basic process for building your web sites. Once you learn what each thing does you will see that Microsoft is doing their best to help you. However, at first it feels like total overkill and a strong-arm tactic to make you do things their way. They are opinionated about what they think you should do, but that is because they’re attempting to provide you with guidance.
Imagine A Wishy-Washy Architect
If you contrast this with someone who makes suggestions and then backs away from those suggestions you will see that Microsoft’s opinionated way is far better.
Imagine an Architect saying, “Well, you could use Node.js and write everything in JavaScript.” He shakes his head. “I don’t know, maybe we should just use AngularJS and follow that. No, no. Maybe we should just use pure JavaScript so we aren’t dependent upon some other company’s library?”
That would be terrible and unhelpful.
Eco-System Is Everything Together
Microsoft has attempted to create an entire eco-system that is based upon :
-
the easiest way to get started,
-
which provides conventions over configuration
-
A set of libraries which they suggest are helpful (jQuery, BootStrap for styling, Razor Pages, etc).
When Starting Out, There's Too Much To Focus On
They try to provide everything you need. However, at the outset you don’t know what you need and everything together feels like a huge pile of stuff. That’s why we are going to go through each thing you find in this template project and show you its intended purpose.
Convention Over Configuration
In the past a lot of frameworks have gotten all tied up in configuration. Most of those configurations started out as small XML files to edit. Later they became a huge morass of XML that developers drowned in. Microsoft has attempted to make configuration work while pushing conventions -- common ways of doing things. They’ve done this so that your life doesn’t devolve into editing XML files. We will discuss this more and decide for ourselves whether or not they’ve succeeded.
Let’s examine everything that the template has added to our project.
The first item we come to under the solution is the project.
If you right click that item and choose properties from the menu which appears it’ll load the project properties in the main window of Visual Studio.
The Application properties of the project will load first.
You can see a number of interesting things here such as the Assembly Name (the DLL or Exe name), the default namespace which was set when you named the project and the Target framework which is obviously .NET Core.
You can also see that the [Output type] is actually considered a [Console Application]. That seems interesting since we know this application runs under a web server.
Application Runs Under Web Server
A web application like this is actually a DLL
(Dynamic Link Library) which is used to extend the normal functionality of the web server it runs under. If you build your project and go out to the location where the app has been built you can see that it is actually a DLL
.
When you build the project, Visual Studio creates a bin\<Target>\netcoreapp2.0\
directory under your project directory. <Target>
is either Debug
or Release
depending upon your build.
After it creates the appropriate directory it places the binary files (DLLs or EXEs) which are required to run the app. A DLL cannot run on its own, but is actually loaded by another process.
In the case of our Web Apps it can be IIS (Internet Information Services web server). However, there is quite a bit of other stuff going on too, because Microsoft does some work to insure the web app will run on Linux and MacOS too.
There are obviously numerous other tabs (down the left side) of the Project properties but we’ll investigate some of those later so we don’t get too far off track right now. Let’s continue looking at what is in the project.
The next item we see is the Connected Services but this project doesn’t include any of those. Connected Services could be things like web services that the project will connect to to retrieve data.
Dependencies
Next, we see the Dependencies item which contains three sub items.
The three sub items are :
-
Analyzers - code and performance analysis
-
NuGet - Package manager which helps retrieve pre-written and built libraries which contain common code you may need to include in your project
-
SDK - The base dotnetcore libraries which support all of Microsoft’s ASP.NET and MVC architecture.
SDK Is Large
The SDK item is very large since it contains everything that Microsoft believes you will need for your ASP.NET Razor Pages app. It’s the entire architecture of their system compiled into libraries for your convenience.
If you expand the SDK item you will find a Microsoft.NETCore.App
item under it and then if you expand that item you will see a huge number of libraries (DLLs) listed.
Since Microsoft doesn’t know how large your dotnet core app will become and what functionality it will use, they are attempting to make everything available to you.
Ease of Use or Bloatware
Of course some devs will call this ease of use and others will call it bloatware.
Properties : launchSettings.json
The next item we come upon in the project is the Properties item and it contains the launchSettings.json
file. If you click the JSON file, it will open up in an editor in Visual Studio.
Because of the problems that developers have confronted in the past with XML Microsoft (and other companies and Open Source) have moved toward JSON (JavaScript Object Notation) for their configuration files. This is an example of that.
What Is JSON?
JSON is simple name-value pairs which can be nested in a hierarchy.
Here’s the format of a simple JSON.
{"name":value}
As the O in the acronym suggests, it is a type of Object notation. So, looking at our example you can see that it is an object that contains one property named name and the value of that property is value.
Here’s a more realistic example:
{"xPosition": 44}
This is an object that contains a property named xPosition which has a value of 44.
Each name is seperated from the value using a : (colon). If you have more than one name/value pair in the object (because it has more than one property) then you seperate each pair using a comma.
{"xPosition": 44, "yPosition":33}
JSON also allows nested structures, meaning that the value can itself be another object.
{"xPosition": 44, "yPosition":33,
SubItem: {"thing": "extra"}}
In this example SubItem is another object which contains one name/value pair (one property named thing
and it’s string value is “extra”
.
Let’s take a closer look at the first block of JSON in the launchSettings.json
.
Because the names are human-readable we can begin to guess what might be going on.
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:54382/",
"sslPort": 0
}
},
You can see on Line 2 that a new object is declared and it has a name of iisSettings.
That object contains a few properties, the first one is windowsAuthentication
which is set to a value of false. So we can guess that the IIS setting for windows authentication is off.
On line 4 we can see that anonymousAuthentication
is also turned on so that means there is no check to see if a user is logged on. That’s why the app just runs and displays content.
On line 5 we see that iisExpress (developer version of IIS) is getting its applicationUrl set to localhost and the port where the app will be listening. If we run the app right now, you will see that the port it loads on will be 54382
.
This is all very nice because it is an easy way to discover how our application is configured.
Of course there is more in the JSON file and we’ll go over those in more depth as we need to work with them. Again, for now, let’s continue down our examination of what is in the base project.
Next, we see the wwwroot
item. This represents the actual deployed web site that our project creates.
You can expand the wwwroot item and see some basic folders under there (css
, images
, js
, lib
) and a favicon.ico.
If you right-click the wwwroot
item and select the [Properties] menu item you will be able to see where this folder is located on your system drive.
These are the files which work with your code which is wrapped up in the FirstDN.dll
.
If you expand each of the folders you can see the basics of what is in each so you know where things are you may need to work on. For example, the site.css is the CSS
(Cascading Style Sheets) which contains all of styles that are displayed on your web site.
Images
You can see there are some images for the banner included. Those are SVG (Scaled Vector Graphics) which can automatically resize themselves without distortion.
JavaScript
Next, you see a site.js file which is currently empty but which provides a place for any JavaScript you may want to include.
Included Libraries
If you look a little further down to the lib folder you will see that the project also includes bootstrap (Twitter Bootstrap) which also applies styles to the site. After that there are some jQuery libraries which help to make doing some of the things on your site much easier. jQuery is used by something like 80% of the web sites out there.
Finally you see the favicon.ico which is the very small icon which can show up on the browser tab when the user loads your site.
Notice, however, that there were no HTML files found under wwwroot at all. That’s because the HTML which is generated is found under the next Solution Explorer item named Pages.
Pages Folder
When you expand the Pages folder you can see a number of CSHTML files.
Those files are Razor-enabled HTML files. That CS
portion of the name stands for CSharp (C#). Razor-enabled simply means that we can add Razor directives
so the Razor View engine
will generate parts of the HTML, instead of only serving up static (unchanging) HTML content.
These are the files which are loaded by the built-in routing engine that routes a URL to these views.
_ViewStart.cshtml
We are going to talk more about how the app starts up and what it does later in this chapter, but now is a good time to talk about the _ViewStart.cshtml file because it is the beginning of how everything starts rendering to the user in a Razor Pages app.
When a Razor pages app is started the Razor view engine is engaged and when it is called the first thing it looks for is the existence of a _ViewStart.cshtml. If it doesn’t find the _ViewStart.cshtml the target URL and page will load as expected, however when it does find the page, it will run the default directive.
The _ViewStart.cshtml page is very small, but it gets other things to load.
A Razor directive has a few different forms and here we see directive block. That simply means that everything wrapped in @{ }
becomes Razor code.
So, in this case we are setting the Razor Layout to be “_Layout”. That tells Razor that it should now load a file named _Layout.cshtml
.
_Layout.cshtml
This is the default view that is loaded for the entire site. It is like a master page which other pages will be included within.
Examining the _Layout.cshtml
will help us understand the entire application because a lot of work goes on in this file.
I’ll break the file down into sections, starting with the entire <head> section so we can examine what goes on.
This is a valid HTML5 document and contains the proper declaration to make it so: <!DOCTYPE html>
There are some meta tags to set the character set which should used to render page and a basic viewport to set scaling on the page.
First Razor Directive
Then, we come to the HTML <title>
tag on Line 6 and we see that our first Razor directive is used. When you want to run code to get a value or generate values you can use a Razor directive. This creates dynamic content.
In this case the directive is: @ViewData[“Title”]
That is telling the Razor engine to load a thing called ViewData
and get an element with a name of “Title”. After it gets that value, it will set the Title of the page to <RetrievedValue>
- FirstDN. The title of the page shows up in the title bar of the browser.
In the example, you can see the value is “Home page - FirstDN”
But where does it load that value (“Home Page”) from.
Well, in this case, when we load the home page, the web site actually loads the Index.cshtml file. So let’s take a moment to examine that file.
More Razor Directives
Right at the top of the Index.cshtml
we see more Razor directives.
@Page : Shortcut To Controller
That first directive is very interesting and a change from the older ASP.NET MVC way of doing things. In the past, there would be a Controller loading this Index.cshtml
View, but the @Page
is a shorthand telling the MVC infrastructure that this page should be considered the Controller also. In cases like this, where we simply want to load a page it makes sense because we don’t have to create the extra cod of the Controller. Instead we add that @Page
directive and this page is loaded.
Next, the page declares a Model object (object to hold some values which represent the page) named IndexModel
, with the following statement:
@model IndexModel
Finally, we get to the code that we were attempting to investigate.
The directive block we see is where the Title value gets set in a ViewData
object. The ViewData
object is basically a global collection that is available for us to add to. It’s like a bucket that we can add named variables too (“Title”) and then use later.
When the Index.cshtml
file is loaded we want to set the ViewData[“Title”]
equal to “Home Page”.
That’s how that value gets set. Later when the _Layout.cshtml
file loads it retrieves the value and displays it in the browser’s title area.
Why A Dynamic Value?
The reason this is a dynamic value is so that different titles can be rendered depending upon which page in your web site is loaded.
That’s made possible by setting the ViewData[“Title”]
to different values when the different sub-pages are loaded. For example, when the About page is loaded, it sets the value to “About” using a similar Razor directive.
You can see it in the About.cshtml
file.
When the user clicks the [About]menu item on the web site and the About.cshtml
file loads the directive is run and the title is set appropriately. You can see the Title is now “About - FirstDN”
ViewData Bucket
You can actually put all manner of data in that collection and we’ll learn more about ViewData
as we continue building more apps.
Let’s make our way back to the _Layout.cshtml
file so we can continue our initial examination.
Environment Tags
After the title tag, there are some <environment>
tags which are never rendered to the user. These are used for development purposes to allow us to include different resources depending upon whether the app is running in production or in development.
System Architecture Exposed
This is just another way Microsoft is attempting to create a System Architecture which helps you be able to easily test and deploy your code and not worry about having to change things later and accidentally deploying test code to production. As any developer who has ever released test code to production which then fails, can attest, this is great stuff.
Basically in these cases, the production version retrieves the bootstrap libraries from a CDN (Content Development Network) which will be more available once the site is exposed to the public. In development, the site simply loads the libraries from your local disk.
_Layout.cshtml Is Basically A Template
You can think of our _Layout.cshtml
file as a template which loads the site resources dynamically.
This is done to help you implement SoC (Separation of Concerns) so that you can change one thing in your project and web site in isolation to other things.
Let’s examine the rest of the file now.
You can see that the document <body>
starts on Line 19 and contains a couple of interesting sections. The first one is a <nav>
element and you can probably guess that HTML for the top menu bar which contains all of the menu items (FirstDN, Home, About, Contact).
That is all basic HTML except there are a couple of AnchorTag Helpers
used to make the Menu elements clickable.
You can see those starting on Line 33.
If you float over the asp-page
portion of any of those links Visual Studio Intellisense will pop up and provide a bit more information about them.
Those are very simple to use. Just type asp-page
and set them equal to a valid URL or route in your system. We’ll talk more about routes as we continue through the material.
@RenderBody : Razor Directive
The next interesting part of the page is on Line 41 where we see the call to @RenderBody()
.
Again, floating over the code will cause Visual Studio to display Intellisense information.
All of this helps us get a better sense of where the framework is doing things for us and helps us to see behind the magic that seems to occur.
The @RenderBody()
is the location where the sub-page will be loaded. The sub-page is the page that the _Layout.cshtml template is referencing. Keep in mind that this _Layout.cshtml
page is the basic template that is displayed on every page. In this case, we can see that every page will have the menu bar. However, after the menu, the main portion of the page is loaded by the sub-pages (index.cshtml
, about.cshtml
, contact.cshtml
).
Those sub-pages are what is loaded by the @RenderBody()
(depending upon which route is loaded -- which menu item the user clicks).
This is made more evident when we switch to the About page, because only the bottom portion changes.
You can also see this is true by examining the source after it is rendered in the browser.
First, notice that Line 40 in _Layout.cshtml sets the <div> to a class of “container body-content”.
Now, we can look for that in the rendered HTML source. Just go to your web browser, right-click the page and select the [View page source] menu item.
In the source, you can see the original div and then the content that is just below that is the content that is rendered by the call to @RenderBody()
.
That is the entire content of the About.cshtml
file:
You can see that the About.cshtml contains one <h2>
tag, one <h3>
tag and one <p>
tag.
The @RenderBody
is the magic that makes it possible to load dynamic content.
About.cshtml.cs File
There is one more bit of magic that is used here. It is a Model
object that provides a way to store data in a structure that you can use later.
If you look closely at the solution explorer you will see that the About
, Contact
, Error
and Index
CSHTML files all can be expanded.
That is because they provide a code-behind file -- which is a pure C# file.
Normally, these objects would surely be much more significant and be Business Objects (things from your software’s problem domain). But in the meager example the project template includes you just see that there is an AboutModel class that has one property called the Message.
When the page is retrieved (HTTP Get is called) the OnGet()
method fires and sets the Message
object to a string value (on line 15).
When that value is set, it can be used in other places in the app.
On the About page (About.cshtml
) it is accessed using a Razor directive in the <h2>
tag.
When the page is rendered that code retrieves the string (“Your application description page.”) and displays it.
Continuing through Solution Explorer we next see two additional JSON files:
-
appSettings.json
: more JSON which helps configure the app. More on this later as we use it.
-
bundleconfig.json
: This is a configuration file to describe how CSS and JavaScript files should be bundled for production deployment. Bundling means compiling multiple files into one and minifying the code. Minifying the code is a way to make CSS and JavaScript files smaller by removing white-space.
You can see that the minified versions of CSS and JS include the .min
file extension within them so you can know which file you are about to view when even when you are in the file system. This is a convention to help organize your files.
Again, all of this is Microsoft helping to do everything they can so that your deployments are easier. This is all part of creating a complete framework which allows you to concentrate on building solutions.
Program and Startup C# Files
Finally, we come to the last two files in the project. These are the files which get the app running and load all the dotnet dependencies so they are available for our use.
When IIS (or other web server) loads your app (loads the FirstDN.dll
) it searches for the Main()
method as the entry point to your application and runs any code found there.
Our Main()
method was created for us by the dotnet core framework and it was added to the Program.cs file.
You can see the Main
method on Line 15.
Odd Looking Lambda Expression Body Definition
The Main()
method calls a local method named BuildWebHost()
which you can see on Line 20.
When it calls that method, the method will return an IWebHost object. When that object is returned the Run()
method is called on it to keep it running in memory until the application is explicitly stopped.
The BuildWebHost uses a lambda expression body definition =>
to define the function so it looks a bit odd.
We could convert that lambda syntax to the following so it would look a bit more normal, and it will still run exactly the same way. You can read more about lambdas and see some additional examples at: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-operator#expression-body-definition
Fluent Interface
The code called in BuildWebHost()
may look a little odd also, since it uses a Fluent Interface. Basically that means each call returns an Object that is then used to call another method.
That is what creates the chaining look of the calls.
So, in this case:
-
CreateDefaultBuilder(args)
returns a WebHostBuilder
Object
-
The UseStartup<Startup>()
method* is called on the WebHostBuilder
and returns the WebHostBuilder
again
-
The returned WebHostBuilder
is used to call the Build()
method which returns the WebHost
which is returned to the Main()
method.
-
Finally the Main()
method calls Run()
on that WebHost
and the application is running.
*Note: When the UseStartup<Startup>()
method is called, the Startup.cs
class is instantiated and it’s code runs.
Startup Constructor Is Called
When the Startup class constructor is called. It adds the MVC libraries to the Services component so that this Razor app will behave according to MVC infrastructure rules.
Then, after the Constructor completes, the app calls into the Configure()
method and some more configuration is completed for you.
You can see this where I set a break point and stepped into the code as the app was loading.
At this point the constructor has loaded and the Configure()
method is running.
What Is The Point of All This?
Again, all of this infrastructure is built in so that you can do the work of application / service development. This infrastructure (as we will see later) is what will allow us to run our Web Application on a Linux box (or macOS). Microsoft is attempting to create the SoC (Separation of Concerns) so you don’t have to know about things unless you need to configure them. And then when you do need to alter things, you will be able to do it in isolation from everything else so you don’t break your entire service.
Now that we have the basics of what is going on we can begin to build a useful app and interact with the dotnet core framework in the appropriate way -- only altering the parts we need.
I hope you see the value in understanding the foundation (ASP.NET Core framework) we are building on and that you feel this has been valuable.
Building Challenging Projects
However, to really learn how a system works you need to build an application that is realistic and useful, otherwise you’ll only know how to build code in small snippets.
ASP.NET Core Blogging Software
That’s why in the next chapter, we will jump into creating our own ASP.NET Core based blogging software.
History
February 3, 2018: first publication