Last week we announced the release of ASP.NET Core 2.0 and described some top new features, including Razor Pages, new and updated templates, and Application Insights integration. In this blog post we are going to dig into more details of features in 2.0. This list is not exhaustive or in any particular order, but highlights a number of interesting and important features.
ASP.NET Core Metapackage/Runtime Store
ASP.NET Core has had a goal of allowing developers to only depend on what they need. While people generally appreciate the increased modularity, it came with an increased cost for everyone in the form of finding and depending on a relatively large set of smaller packages. In 2.0 we have improved this story with the introduction of the Microsoft.AspNetCore.All package.
Microsoft.AspNetCore.All is a metapackage, meaning it only has references to other packages, and it references:
- All ASP.NET Core packages.
- All Entity Framework Core packages.
- All dependencies used by ASP.NET Core and Entity Framework Core
The version number of the Microsoft.AspNetCore.All metapackage represents the ASP.NET Core version and Entity Framework Core version (aligned with the .NET Core version). This makes it easy to depend on a single package and version number that gives you all available APIs and lines up the entire stack.
Applications that use the Microsoft.AspNetCore.All metapackage automatically take advantage of the .NET Core Runtime Package Store. The runtime store contains all the runtime assets needed to run ASP.NET Core 2.x applications on .NET Core. When you use the Microsoft.AspNetCore.All metapackage, no assets from the referenced ASP.NET Core packages are deployed with the application — the .NET Core Runtime Store already contains these assets. The assets in the runtime store are precompiled to improve application startup time. This means that by default if you are using the Microsoft.AspNetCore.All metapackage your published app size will be smaller and your apps will startup faster.
You can read more about the .NET Core Runtime Package Store here: https://docs.microsoft.com/en-us/dotnet/core/deploying/runtime-store
WebHost builder APIs
The WebHost builder APIs are static methods in the Microsoft.AspNetCore package that provide several ways of creating and starting a WebHost with a default configuration. These methods reduce the common code that the majority of ASP.NET Core applications are going to need. For example. you can use the default web host builder like this:
The above code is taken from the MVC template in Visual Studio, and shows using the CreateDefaultBuilder method to construct a WebHost. You can see the configuration that CreateDefaultBuilder uses here.
The Program.BuildWebHost method is provided by convention so that tools, like EF migrations, can inspect the WebHost for the app without starting it. You should not do anything in the BuildWebHost method other than building the WebHost. We used an expression-bodied method in the templates to help indicate that this method shouldn’t be used for anything other than creating an IWebHost.
In addition to CreateDefaultBuilder there are a number of Start methods that can be use to create and start a WebHost:
These methods provide a way to run an application in a single line of code, but more importantly they provide a way to quickly get a web server responding to requests and executing your code without any ceremony or extra configuration.
Configuration as a Core service
As we watched developers build applications with 1.x, and listened to the feedback and feature requests being made, it become obvious that there are several services that should always be available in ASP.NET Core. Namely, IConfiguration, ILogger (and ILoggerFactory), and IHostingEnvironment. To that end in 2.0 an IConfiguration object will now always be added to the IoC container, this means that you can accept IConfiguration in your controller or other types activated with DI just like you can with ILogger and IHostingEnvironment.
We also added a WebHostBuilderContext to WebHostBuilder. WebHostBuilderContext allows these services to be configured earlier, and be available in more places:
The WebHostBuilderContext is available while you are building the WebHost and gives access to an IHostingEnvironment and IConfiguration object.
There are three main differences in the way that Logging can be used in 2.0:
- Providers can be registered and picked up from DI instead of being registered with ILoggerFactory, allowing them to consume other services easily.
- It is now idiomatic to configure Logging in your Program.cs. This is partly for the same reason that configuration is now a core service: you need Logging to be available everywhere, which means it should be configured early.
- The log filtering feature that was previously implemented by a wrapping LoggerFactory is now a feature of the default LoggerFactory, and is wired up to the registered configuration object. This means that all log messages can be run through filters, and they can all be configured via configuration.
In practice what these changes mean is that instead of accepting an ILoggerFactory in your Configure method in Startup.cs you will write code like the following:
The Kestrel web server has new features that make it more suitable as an Internet-facing server. We’ve added a number of server constraint configuration options in the KestrelServerOptions class’s new Limits property. You can now add limits for the following:
- Maximum client connections
- Maximum request body size
- Minimum request body data rate
The packages Microsoft.AspNetCore.Server.WebListener and Microsoft.Net.Http.Server have been merged into a new package Microsoft.AspNetCore.Server.HttpSys. The namespaces have been updated to match.
For more information, see Introduction to Http.sys.
Automatic Page and View compilation on publish
Razor page and view compilation is enabled during publish by default, reducing the publish output size and application startup time. This means that your razor pages and views will get published with your app as a compiled assembly instead of being published as .cshtml source files that get compiled at runtime. If you want to disable view pre-compilation, then you can set a property in your csproj like this:
If you do this you will have .cshtml files in your published output again, as well as all the reference assemblies that might be required to compile those files at runtime.
Tag Helper components
Tag helper components are responsible for generating or modifying a specific piece of HTML. They are registered as services and optionally executed by TagHelpers. For example, the new HeadTagHelper and BodyTagHelper will run all the registered tag helper components, so they can modify the head or body of page being rendered.
If you register an IHostedService then ASP.NET Core will call the Start() and Stop() methods of your type during application start and stop respectively. Specifically, start is called after the server has started and IApplicationLifetime.ApplicationStarted is triggered.
Today we only use hosted services in SignalR, but we have discussed using it for things like:
- An implementation of QueueBackgroundWorkItem that allows a task to be executed on a background thread
- Processing messages from a message queue in the background of a web app while sharing common services such as ILogger
If you read the ASP.NET Core 2.0 announcement blog post then you will have seen a lot of talk about automatic light-up of Application Insights. When you publish to an Azure App Service and enable Application Insights you get log messages and other telemetry “for free”, meaning that you don’t have to add any code to your application to make it work. This automatic light-up feature is possible because of the IHostingStartup interface and the associated logic in the ASP.NET Core hosting layer.
The IHostingStartup interface defines a single method: void Configure(IWebHostBuilder builder);. This method is called while the WebHost is being built in the Program.cs of your ASP.NET Core application and allows code to setup anything that can be configured on a WebHostBuidler, including default services and loggers which is how Application Insights works. ASP.NET Core will execute any IHostingStartup implementations in the applications assembly as well as any that are listed in an Environment Variable called ASPNETCORE_HOSTINGSTARTUPASSEMBLIES.
Improved TempData support
We’ve made a couple of improvements to the TempData feature in this release:
- The cookie TempData provider is now the default TempData provider. This means you no longer need to setup session support to make use of the TempData features
- You can now attribute properties on your controllers and page models with the TempDataAttribute to indicate that the property should be backed by TempData. Set the property to add a value to TempData, or read from the property to read from TempData.
Media type suffixes
ASP.NET Core MVC now supports media type suffixes (ex. application/foo+json). The JSON and XML formatters have been updated to support the json and xml suffixes respectfully. For example, the JSON formatters now support parsing requests of the form Content-Type: application/*+json (with any parameters), and support formatting responses when your ObjectResult’s ContentTypes or Response.ContentType value are of the form application/*+json. We’ve extended the MediaType API to add SubtypeSuffix and SubtypeWithoutSuffix properties, and you can use wildcard patterns to indicate support for media type suffixes on your own formatters.
As you can see there is a lot of new stuff in ASP.NET Core 2.0. We hope you enjoy trying out these new features. Download .NET Core 2.0 today and let us know what you think!