Skip to main content

Our Journey

Why don't you go with us?

Announcing ASP.NET Core 2.0

Generic responsive image

With the ASP.NET Core 2.0 release we’ve added many new features to make building and monitoring web apps easier and we’ve worked hard to improve performance even more.

Updating a Project to ASP.NET Core 2.0

ASP.NET Core 2.0 runs on both .NET Framework 4.6.1 and .NET Core 2.0, so you will need to update your target framework in your project to netcoreapp2.0 if you were previously targeting a 1.x version of .NET Core.

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
view rawmyproject.csproj hosted with ❤ by GitHub

Figure 1 - Setting Target Framework in Visual Studio 2017

Figure 1 – Setting Target Framework in Visual Studio 2017

Next, we recommend you reference the new Microsoft.AspNetCore.All metapackage instead of the collection of individual Microsoft.AspNetCore.* packages that you previously used.  This new metapackage contains references to all of the AspNetCore packages and maintains a complete line-up of compatible packages.  You can still include explicit references to specific Microsoft.AspNetCore.* package versions if you need one that is outside of the lineup, but our goal is to make this as simple a reference as possible.

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" />
</ItemGroup>
view rawmyproject.csproj hosted with ❤ by GitHub

What happens at publication time?  We know that you don’t want to publish the entire AspNetCore framework to your target environments, so the publish task now distributes only those libraries that you reference in your code.  This tree-pruning step should help make your publish process much smoother and easier to distribute your web applications.

More information about the features and changes you will need to address when migrating from ASP.NET Core 1.x to 2.0 can be found in our documentation.

Introducing Razor Pages

With this release of ASP.NET Core, we are introducing a new coding paradigm that makes writing page-focused scenarios easier and simpler than our current Model-View-Controller architecture.  Razor Pages are a page-first structure that allow you to focus on the user-interface and simplify the server-side experience by writing PageModel objects.

If you are familiar with how to configure your ASP.NET Core Startup class for MVC, then you already have the following lines in your Startup class:

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Includes support for Razor Pages and controllers.
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
}
}
view rawstartup.cs hosted with ❤ by GitHub

Surprise!  The AddMvc and UseMvc configuration calls in your Startup class also activate the Razor Pages feature.  You can start writing a Razor Page by placing a new cshtml file called Now.cshtml in the Pages/ top-level folder of your application.  Let’s look at a simple page that shows the current time:

@page
<html>
<body>
<h2>The server-local time now is:</h2>
<p>@DateTime.Now</p>
</body>
</html>
view rawnow.cshtml hosted with ❤ by GitHub

This looks like a standard MVC View written in Razor, but also has the @page directive at the top to indicate that this is a stand-alone Razor Page built with that paradigm.  HtmlHelpersTagHelpers, and other .NET Code is available to us in the course of the page.  We can add methods just as we could in Razor views, by adding a block level element called @functions and writing methods into that element:

@page
@functions {
public string FormatDate(DateTime theTime) {
return theTime.ToString("d");
}
}
<html>
<body>
<h2>The server-local time now is:</h2>
<p>@FormatDate(DateTime.Now)</p>
</body>
</html>
view rawnow.cshtml hosted with ❤ by GitHub

We can build more complex structures by taking advantage of the new PageModel object.  The PageModel is an MVVM architectural concept that allows you to execute methods and bind properties to the Page content that is being rendered.  We can enhance our sample by creating a NowModel.cshtml.cs C# class file in the Pages folder with this content:

namespace MyFirstRazorPage.Pages
{
public class NowModel : PageModel
{
private IFileProvider _FileProvider;
public NowModel(PhysicalFileProvider fileProvider)
{
_FileProvider = fileProvider;
LastModified = _FileProvider.GetFileInfo("Pages/Now.cshtml").LastModified.LocalDateTime;
}
public DateTime LastModified { get; set; }
public void OnGet() { }
}
}
view rawNowModel.cshtml.cs hosted with ❤ by GitHub

With this class that inherits from PageModel, we can now do more complex interactions and build out a class that can be unit tested.  In this case, we are simply loading the LastModified property on the Now page and setting that to the LastModified property.  Also note the OnGet method to indicate that this PageModel handles the HTTP GET verb.  We can update our Razor Page with the following syntax to start using the PageModel and output the last update date:

@page
@model MyFirstRazorPage.Pages.NowModel
<html>
<body>
<h2>This page was last updated:</h2>
<p>@Model.LastModified</p>
</body>
</html>
view rawnow.cshtml hosted with ❤ by GitHub

For more information, check out the ASP.NET Core documentation on getting started with Razor Pages.

Updated Templates and SPA Templates

The templates that ship with ASP.NET Core have been enhanced to not only include a web application that is built with the MVC pattern, but also a razor pages web application template, and a series of templates that enable you to build single-page-applications (SPA) for the browser.  These SPA templates use the JavaScript Services functionality to embed NodeJS within ASP.NET Core on the server, and compile the JavaScript applications server-side as part of the .NET build process.

New ASP.NET Core Templates in Visual Studio 2017

Figure 2 – New ASP.NET Core Templates in Visual Studio 2017

These same templates are also available out of the box at the command-line when you type dotnet new:

Figure 3 – Templates available with the dotnet new command

DbContext Pooling with Entity Framework Core 2.0

Many ASP.NET Core applications can now obtain a performance boost by configuring the service registration of their DbContext types to use a pool of pre-created instances, avoiding the cost of creating new instance for every request.  Try adding the following code to your Startup/ConfigureServices to enable DbContext pooling:

services.AddDbContextPool<BloggingContext>(
options => options.UseSqlServer(connectionString)
);
view rawstartup.cs hosted with ❤ by GitHub

You can read more information about the updates included in Entity Framework Core 2.0 online in their announcement post.

Monitor and Profile with No Code Changes and Application Insights

ASP.NET Core 2.0 runs with no modifications necessary on Azure App Service and comes with integrations that provide performance profiling, error reporting, and diagnostics from Azure Application Insights. In Visual Studio 2017, right-click on your project and choose “Add – Application Insights Telemetry” to start collecting data from your application. You can then review the performance of your application including all log messages directly within Visual Studio 2017.

Telemetry Reported in Visual Studio 2017

Figure 4 – Telemetry Reported in Visual Studio 2017

That’s nice when you’re developing your application, but what if your application is already in Azure?  We’ve got support in the Azure portal to start profiling and debugging, and it starts when you first publish your application and navigate to the cloud portal for your new app service.  Azure will prompt you with a new purple banner indicating that Application Insights for monitoring and profiling is available

Banner in Azure Portal offering to assist in configuring Application Insights

Figure 5 – Banner in Azure Portal offering to assist in configuring Application Insights

When you click through that banner, you will create an Application Insights service for your application and attach those features without recompiling or redeploying.  Shortly afterwards, your new Application Insights service will start reporting data about the activity captured.

Initial Application Insights Overview on Azure Portal

Figure 6 – Initial Application Insights Overview on Azure Portal

It even shows the number of failed requests and errors in the application.  If you click through that area, you’ll see details about the failed requests:

Failed Requests Report on Azure Portal

Figure 7 – Failed Requests Report on Azure Portal

There is a System.Exception thrown, and identified at the bottom of the screen, if we click through that reported exception, we can see more about each time that exception was thrown.  When you click through a single instance of those exceptions, you get some neat information about the exception including the call stack:

Exception Analysis in the Azure Portal

Figure 8 – Exception Analysis in the Azure Portal

Snapshot debugging in Application Insights now supports ASP.NET Core 2.0.  If you configure snapshot debugging in your application, then the “Open Debug Snapshot” link at the top will appear and show the complete call stack and you can click through method calls in the stack to review the local variables:

Stack Trace in Azure Portal

Figure 9 – Stack Trace in Azure Portal

Local values reported in Azure Portal

Figure 10 – Local values reported in Azure Portal

 

Nice!  We can go one step further and click that “Download Snapshot” button in the top corner to start a debug session in Visual Studio right at the point this exception was thrown.

What about the performance of these pages?  From the Application Insights blade, you can choose the Performance option on the left and dig deeper into the performance of each request to your application.

Application Profiling in Azure Portal

Figure 11 – Application Profiling in Azure Portal

There are more details available in our docs about performance profiling using Application Insights.

If you want the raw logs about your application, you can enable the Diagnostic Logs in App Service and set the diagnostic level to Warning or Error to see this exception get thrown.

Configure Logging within the Azure Portal

Figure 12 – Configure Logging within the Azure Portal

Finally, choose the Log Stream on the left and you can watch the same console that you would have on your developer workstation.  The errors and log messages of the selected severity level or greater will appear as they are triggered in Azure.

Live Console Logging inside the Azure Portal

Figure 13 – Live Console Logging inside the Azure Portal

All of the Application Insights features can be activated in ASP.NET Core without rebuilding and deploying.  Snapshot debugging requires an extra step and some code to be added, and the configuration is as simple as an extra NuGet package and a line in your Startup class.

You can learn more about Application Insights Telemetry in our online documentation.

Razor Support for C# 7.1

The Razor engine has been updated to work with the new Roslyn compiler and that includes support for C# 7.1 features like Default ExpressionsInferred Tuple Names, and Pattern-Matching with Generics.  To use C #7.1 features in your project add the following property in your project file and then reload the solution:

<LangVersion>latest</LangVersion>

C# 7.1 is itself in a preview state, and you can review the language specification for these features on their GitHub repository.

Simplified Application Host Configuration

Host configuration has been dramatically simplified, with a new WebHost.CreateDefaultBuilder included in the default ASP.NET Core templates that automatically allocates a Kestrel server that will attempt to run on IIS if it is available, and configures the standard console logging providers.  Your Program.cs file is simplified to only this content:

public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
view rawprogram.cs hosted with ❤ by GitHub

That reduces the possibility of accidentally breaking some of the standard configuration that most developers were not altering in their ASP.NET Core applications.  Why make you write the same boilerplate code over and over, when it could be simplified to 3 lines of code?