Thursday, May 19, 2016

ASP.NET Core 1 - Blank Template Part 2

 

In my last post I walked through the code of the blank template that is created for an ASP.NET Core 1 RC1 application. In this post we will take a closer look at the how this application works.

First let’s run the application by clicking the IIS Express button in Visual Studio.

image

Your browser should open and display the message “Hello World!”. If you look in your system tray you will find IIS Express serving up WebApplication1 so you application is running on IIS. If you now go into your browser’s debugging tools (for example, press F12 in Internet Explorer), go to network monitor and refresh the page you will be able to view response header:

image

You can see that even though we are running on IIS, the web server is reported as Kestrel since that is the actual server we are running on, IIS is just serving as a reverse proxy passing the requests to Kestrel.

Next click the down arrow next to IIS Express:

image

In the list below IIS Express you will see all the commands that have been declared in the project.json file. In the blank template there is only one command “web”. Click on web to start the application using this command. This time instead of a web browser opening you will see a window like this:

image

In this case we are running directly on Kestrel instead of Kestrel running behind IIS. To view the output of the application use the URL that is being listened on shown in the window, in this case http://localhost:5000. You will not see IIS Express in the system tray and if you look at the network monitor it will still show the server as Kestrel.

Now let’s look at the IISPlatformHandler. This piece of middleware allows Windows Integrated Authentication and TLS Authentication to pass through to Kestrel. In Startup.cs change the line that displays “Hello World” to this:

await context.Response.WriteAsync("Hello " + context.User.Identity.Name);

Just like previous versions of ASP.NET you can use the User property of the HttpContext to get authentication information. To run your app in IISExpress using Windows Authentication go to the project properties, go to the Debug tab, make sure the IISExpress profile is selected and then uncheck Enable Anonymous Authentication, and check Enable Windows Authentication.

If you run this using IISExpress you will see your account name if you are on a Windows domain, or you will be prompted to enter your username and password and again the name will be displayed. In this scenario the IISPlatformHandler is handling the authentication and passing their information along to Kestrel in the context.

Now run the application use the web command. When you browse to the page this time you will just get “Hello”. In this scenario we are connecting directly to Kestrel and not going through IISExpress so the IISPlatformHandler doesn’t have an effect.

With the web page displayed try adding a file to the end of the URL, for example http://localhost:63694/test.html. When your browse to this URL the page will still return “Hello”. How about adding a path, http://localhost:63694/test/test.html. Again you will only get “Hello” as a response. As I mentioned in my introductory article ASP.NET Core 1 applications have no functionality by default, not even the ability to server files. Every URL we use just runs the same middleware to display the hello message. In the a future post I will show how to enable various pieces of stock middleware to enable these features.

I hope the demonstrations in this article give you a better idea of some of the differences between the new ASP.NET and previous versions.

Sunday, May 8, 2016

ASP.NET Core 1–Blank Template

 

In my last post I talked about some of the basics of ASP.NET Core 1, in this posted we will get setup to do some development and take a look at some code. I am going to be working on Windows using Visual Studio but the concepts still apply to doing ASP.NET on Mac or Linux. As of this writing the current version of ASP.NET Core 1 (which was formally know as ASP.NET 5) is RC1 and that is what this article is based on.

The instructions for setting up ASP.NET Core 1 on Windows can be found here:

http://docs.asp.net/en/latest/getting-started/installing-on-windows.html

That site also has instructions for getting setup on Mac and Linux. I did this install on two different systems. It worked fine on one, but on the other, when I created a new project in Visual Studio, I got an error saying “Method not found: 'Newtonsoft.Json.Linq.JValue Newtonsoft.Json.Linq.JValue.CreateNull()'.”. I eventually figured out that I had version 6.0.0 of Json.NET installed in the GAC. I installed version 6.0.6 to the GAC and this resolved the problem.

Once you have completed the installation, start up Visual Studio 2015 and select New Project and then under C#, Web, pick ASP.NET Web Applciation. If you have installed everything properly you should see a section called ASP.NET 5 Templates.

Capture.JPG

We will start with a very basic application so select the Empty project type and be sure Host in the cloud is unchecked.

Let’s take a look at some of the files that make up the default Empty project. We will start with project.json. This file basically replaces web.config, although there is a web.config in the project which I will talk about later, and is required by the DNX runtime to execute the application.

"version": "1.0.0-*",

The first line is just a piece of metadata that declares the version of you application. You can also specify things like “authors” or “description”.

"compilationOptions": {
"emitEntryPoint": true
},

Next we have the compiler options. The only option that is included by default is “emitEntryPoint”. If this is set to true then the project will be an executable, if it’s false the project will be a DLL that since it will have no execution entry point.

"dependencies": {
  "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
  "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final"
},

The next section, dependencies, declares the assemblies that this project needs to run. These will normally come from NuGet but also could come from other projects. The two dependencies declared by default are used to handle the web hosting of the application. As I mentioned in my previous post, ASP.NET Core 1 is not tied to any specific web server. Here we see a reference to Microsoft’s open source and cross platform Kestrel web server. This compact web server will run as part of your application and can handle requests directly or can run behind and existing web server. Note that Kestrel is not a full featured web server like IIS, other packages will need to be included in your project to do even simple things like serving static files.

The other dependency is the IISPlatformHandler, which is needed when you are running Kestrel behind IIS. In this configuration IIS simply serves as a reverse proxy passing requests back and forth to Kestrel. The IISPlatformHandler allows things like Windows Authentication to pass through to your application.

"commands": {
  "web": "Microsoft.AspNet.Server.Kestrel"
},

This section defines entry points for your application that can be run from the command line or Visual Studio. When you execute the program using a command it will looks for a Main function in the specified assembly and start execution there. Commands can also have command line options that will get passed to the Main function. You can have multiple commands in a project that allow it to be run in different ways.

"frameworks": { 
  "dnx451": { }, 
  "dnxcore50": { }
},

The next section defines the frameworks that the application can run with. As of this writing you have the options of three version of the full .NET Framework, dnx451, dnx452, and dnx46, and also the .NET Core Framework, dnxcore50. In the default project both core and the full framework are selected, so the application can only use features that exist in both frameworks.

"exclude": [
  "wwwroot",
  "node_modules"
],

In ASP.NET Core 1 you have the option of deploying all your source files to the server and they will be compiled into memory when the application is first started. Every file in the folder with a project.json file, and any subfolders will become part of the program. You can prevent files from being included in the project by setting up exclusions. Here we are excluding the contents of the wwwroot and node_modules sub directories.

"publishExclude": [
  "**.user",
  "**.vspscc"
]

The final section is similar to the exclude section, but this one specifies files that you don’t want published along with your project.

I mentioned earlier that even though project.json takes the place of Web.Config you will still see a Web.Config file in the wwwroot directory of the default template. This file configures the httpPlatformHandler which is an IIS module that allows it to serve as a proxy in front of another web server, in this case acting as a proxy for Kestrel. This module is only used on Windows when running behind IIS.

The final file we will look at is Startup.cs which contains that code that is called to start up your application. Let’s start with the last line:

public static void Main(string[] args) => WebApplication.Run<Startup>(args);

This is the Main function that will be called if you start the application from the DNX command line. It simply starts the web application and passes the command line arguments. If you are running the application using IIS or IIS Express this function will be skipped and WebApplication.Run will be called directly.

When the web application is started up the first function in this class that will be called is ConfigureServices. This class is used to setup any services that your application will need, for example EntityFramework, and makes these services available for dependency injection. In the empty template nothing is done in this function.

The final part of the startup process is a call to the Configure function which looks like this:

public void Configure(IApplicationBuilder app)
{
  app.UseIISPlatformHandler();
  app.Run(async (context) =>
  {
     await context.Response.WriteAsync("Hello World!");
  });
}

The purpose of this function is to build the HTTP request pipeline. As I mentioned in my introductory article, ASP.NET Core 1 applications have almost no functionality out the box. They can receive HTTP requests, but without some setup they can’t do anything with them. The Configure function sets up the processing pipeline be enabling one or more piece of Middleware. Middleware receives an HTTP request, does some sort of processing based on it, and then either returns a response to the requestor, or calls the next piece of Middleware in the chain.

In the blank template you will find two pieces of Middleware. The first is the IIS Platform Handler. This Middleware is used to handle IIS specific authentication like Windows Integrated Authentication. This is only useful when running behind IIS, so it wouldn’t have any function when running on Mac or Linux. When this Middleware completes its task it sends the request on to the next piece of Middleware.

The final piece of code is the one that actually sets up what this application will do, which is to simply return the text “Hello World!” to the calling browser. The app.Run function adds and inline delegate that will be called each time a request to this application is recieved by the server. When called it calls the WriteAsync function to write the text back to the response.

In this post I showed the ground work for a very basic ASP.NET Core 1 application. In my next post we will do a little more with this application to get a better understanding of how things work.