The evolution of Microsoft web frameworks. ASP.NET vNext

    Preconditions for Change

    The news about the release of ASP.NET vNext on the network spread quite quickly, along with the announcement of the most interesting innovations proposed in the update. ASP.NET MVC 6 received a new name and is positioned as something truly new in the Microsoft web framework framework (MS). In order to most fully understand the importance of the announced vNext changes, we recall the features of the current implementation of web applications on the .NET platform.

    A typical ASP.NET MVC application consists of a Global.asax file in which we extend the HttpApplication class (System.Web) and thus add the desired behavior for processing Http requests by configuring the individual components of the MVC. In the classic ASP.NET MVC, the Router class (System.Web.Routing) is an integral part of processing Http requests, by redirecting them to the desired HttpHandler - in the standard behavior (MvcRouteHandler) which creates a controller factory and starts a further request processing pipe. These components are obviously closely tied to MS's web server, Internet Information Services (IIS), which uses HttpHandlers and HttpContext (access to http request / response parameters) to process requests. Legacy from ASP. NET Web Forms ubiquitous use of these components in MVC implied tight integration with IIS, which made it impossible to use an alternative web server for hosting applications. These circumstances over time caused more criticism from the developer community and were really not a very favorable factor in the development of ASP.NET MVC, which as an open source project is developing much faster than Microsoft is developing updates for System.Web components.

    An attempt to rectify the situation was made as part of the development of the Web Api project. During the migration from the MS WCF framework, the developers abandoned the approach to building RESTful services based on the concept of “contract bindings”, in favor of a more convenient MVC, which predetermined a lot of common and consonant name - ASP.NET Web Api. In fact, the developers of the new framework were able to make it with an eye to the ASP.NET MVC flaws described above. Web Api did not use these same System.Web components directly thanks to the adapters for HttpContext.Request, HttpContext.Response - abstractions with the updated HttpRequestMessage, HttpResponseMessage structure into which the HttpControllerHandler (the entry point to the Web Api application) converted the specified objects. The dependency on IIS HttpHandlers was also eliminated,

    All these changes made the Web Api application independent of the host and developed within the framework of the OWIN (Open Web Interface) specification. The key was the concept of middleware - web application components (in IIS - HttpModules) and application delegate, which instead of HttpContext interacts with a much more abstract set of request / response parameters in a hashmap of the form IDictionary.

    Despite all the advantages, flexibility, improved extensibility, and a number of fixes for architectural weaknesses, Web Api still could not become a full-fledged replacement for MVC being focused on Single Page Applications (SPA). At the same time, one framework did not interfere with the other. Moreover, they got along well in the same web application if IIS was used for their hosting and could even use common Http modules, for example, for authentication. Nevertheless, the considered approach required a clear separation of responsibilities in the application and taking into account the peculiarity that Web Api and Mvc use a completely different pipeline for processing requests. The latter added a different kind of complexity to the developers and suggested subsequent refactoring in the new version of the framework, which was called vNext.

    ASP.NET vNext Project Template

    The first thing that catches your eye in the new web application is the lack of web.config, packages.config, and even AssemblyInfo.cs configuration files.

    In the solution structure, we have only two files:
    • project.json - the configuration file for the project, where there are dependencies indicating the versions of plug-in assemblies, project compilation options, metadata, a list of dependencies for deployment in .NET and Core CLR modes.
    • Startup.cs - entry point, web application class.

    Now, having looked at the properties of the VS project, we will not see the abundance of options that ASP.NET projects used to be equipped with. In total, two tabs are available: General - configuration of the namespace and type of application during construction; on the Debugging tab, the port number on which our application will be available.
    Further more interesting is the actual project.json configuration file of the project. It looks approximately as follows.

    The primary set provides for only two keys.
    • dependencies - specifying dependencies for the project obtained from assemblies, NuGet Packages, and even source codes on the disk;
    • configurations - a list of dependencies when building a project for a specific target environment: .NET or Core CLR.

    Such drastic changes in the structure of the project are due to the use of the new Roslyn compiler, which allows runtime to compile the source code in IL and execute it. Roslyn’s capabilities underpinned the new K Language Runtime (KLR). At the moment, it has two options for launching the project in .NET Desktop mode, or Core CLR (in the alpha version, the mode is available only in KLR from under Win 8). You can also build a project using the K Versions Manager (KVM) / K Packages Manager (KPM) - console utilities supplied with K, which allow you to independently manage installed versions of KRE (K Runtime Engine), unpack applications based on project.json and run them. For more information, check out .

    ASP.NET vNext Web Application Structure

    The only source code file in the project - Startup.cs, contains a link to the Microsoft.AspNet.Builder namespace and a class structure similar to OWIN based applications. It has one method - Configure with an input parameter of type IBuilder. The project compiles and starts, but does not return anything as an answer (more precisely, returns “403rd”, since IIS is not finding a request handler trying to access the file system), which is logical, since we did not add any middleware.

    At we are invited to call the static extension method (UseWelcomePage) to add the simplest Request Handler, but it is of little interest to us, as it hides the specifics of the IBuilder interface. Let's try to "dig" a deeper look at its definition:

    using System;
    namespace Microsoft.AspNet.Builder
        public interface IBuilder
            IServiceProvider ApplicationServices { get; set; }
            IServerInformation Server { get; set; }
            RequestDelegate Build();
            IBuilder New();
            IBuilder Use(Func middleware);

    In order to navigate the code, you need to remember that the concept of middleware in OWIN refers directly to the Application Delegate, which receives a list of Http request parameters and performs some kind of conversion on it, returning Task.

    Func, Task>

    For OWIN, we also had a static Extensions method at the IAppBuilder interface level, which allowed us to add middleware using a more convenient structured version of the context - IOwinContext. It has changed a bit in vNext, since it involves working with the HttpContext directly. The latter is now in the Microsoft.AspNet.Http namespace, and has nothing to do with the HttpContext from System.Web, as was the case with the HttpContextBase wrapper in ASP.NET MVC:

    public delegate Task RequestDelegate(HttpContext context);

    Thus, everything gradually falls into place - RequestDelegate in vNext is the very OWIN Application Delegate.
    To add new middleware in the original implementation of the Use method, we pass a generic delegate containing a nested delegate of type RequestDelegate as a parameter. The external Generic delegate refers to the entire further pipeline for processing http requests, RequestDelegate - does the work of the Http Handler.
    Let's try to look at an example with the addition of modules - this should clarify the situation a bit.

    public void Configure(IBuilder app)
                app.Use(next =>
                      httpContext =>
                            httpContext.Response.WriteAsync("Executed before all  followers." + Environment.NewLine)
                            .ContinueWith(task => next(httpContext)));
                app.Use(next =>
                  httpContext =>
                        .ContinueWith(task => 
                            httpContext.Response.WriteAsync("Executed after all followers." + Environment.NewLine)));
                app.Use((httpContext, next) => httpContext.Response.WriteAsync("Hello world middleware." + Environment.NewLine));

    As you can see, when configuring middleware, we have a behavior much similar to Delegating Handlers Web Api, where we can flexibly control the execution sequence from the current module of the entire further pipeline (next parameter). Simply add Http request processing inside the lambda expressions passed to Use.

    As for OWIN itself, vNext is fully compatible with this interface. The Microsoft.AspNet.Builder namespace contains a class of static extension methods for IBuilder that create adapters for transitioning from Owin Application Delegate to vNext RequestDelegate.

    using AddMiddleware = Action, Task>,  Func, Task>>>;
            public static AddMiddleware UseOwin(this IBuilder builder)

    In our application, we can use AddMiddleware for the interaction between the OWIN Environment dictionary and the vNext HttpContext, relying on the internal implementation of the platform. The extension will make it easy enough to use OWIN components in the new version of the framework.

    Of the important features, it is worth noting that, unlike OWIN AppBuilder, the vNext IBuilder interface also contains the built-in ApplicationServices service locator initialized by the application by the web server. This property provides Web Host Application Level Services access.

    vNext HttpContext

    With the structure of the application a little figured out what the updated vNext HttpContext is. As expected, the context class itself, Request and Response, are declared abstract. The HttpContext in the implementation of the Microsoft.AspNet.Hosting host supplied from the crib is instantiated by the DefaultHttpContext object before each call to the middleware chain. The context has the Abort method, implements the IDisposable interface, and provides two service locators ApplicationServices and RequestServices with the corresponding container life cycle, which clearly speaks in favor of a more convenient formation of the Structure Map at the application level compared to previous versions of ASP.NET MVC.

    VNext adds a new context extensibility mechanism by using HttpFeatures. At the context interface level, it provides two sets of methods for obtaining and adding extensions (via packing in object and generic wrapper):

          public abstract object GetFeature(Type type);
            public abstract void SetFeature(Type type, object instance);
            public virtual T GetFeature()
                return (T)GetFeature(typeof(T));
            public virtual void SetFeature(T instance)
                SetFeature(typeof(T), instance);

    In the updated version of ASP.NET, this approach is used to dynamically form a context starting from the first call to HttpContext, where the Host Application / Server Specific Features are initialized and up to the level of request parameters, authentication, caching, and working with web sockets by individual middleware components. In the basic implementation, Request almost completely uses the interfaces defined in Microsoft.AspNet.Builder to get components from HttpFeatures. The formation of the context in this way allows you to hide behind the specific interface of a separate component a specific web server-specific implementation of functionality at the host level, not limited to the basic structure of HttpContex.

    vNext MVC

    The most expected innovation from the point of view of building the web application itself is certainly the combination of ASP.NET MVC and Web Api functionality within the framework of one framework, which will allow using a common pipeline for processing Http requests.

    Adding MVC behavior to vNext involves connecting and configuring two middleware modules:
    • vNext Dependency Resolver with a list of services that form the vNext MVC stack.
    • Router middleware - the MVC module of the router.

        public void Configure(IBuilder app)
                app.UseServices(services => services.AddMvc());
                app.UseMvc(router =>
                    defaults: new { Controller = "Home", Action = "Index" }));

    The first of these is a set of services that provides the implementation of standard MVC components and is used throughout the pipeline to process the request at the level of individual abstractions. These are providers of Action contexts, controller factories, model bindings, View Engine provisioning, etc. Description of services with DI mappings is available for review in the class Microsoft.AspNet.Mvc.MvcServices.cs.

    The second is RouterHandler, which is represented in vNext by the IRouter interface with the asynchronous RouteAsync method:

      public interface IRouter
            Task RouteAsync(RouteContext context);
            string GetVirtualPath(VirtualPathContext context);

    By default, the interface implements the MvcRouteHandler class. Unlike previous versions of routing based on framework-specific functionality (in MVC - HttpHandler, Web Api - DelegatingHandler), this time it only provides for calling individual interface methods received from a service locator with a set of MVC components. It is this class that receives the ActionContext and starts the further pipeline for processing the request using the IActionInvoker service in conjunction with the ControllerFactory. The main advantage of using this approach is obvious, it provides the necessary versatility for merging frameworks, which was absent before.

    Another positive change in the new version of MVC is the completely asynchronous execution mode of service methods. In a similar way, pipe was implemented in Web Api and made it possible to completely remove operations related to waiting for resources from the working pool of a web server stream. Until now, MVC provided “out of the box” only asynchronous controllers.

    The main work unit for processing the Http request in vNext was taken from MVC. For post-processing and serialization of the results of actions, the IActionResult interface is used. Functionality MVC in this respect conceptually remained the same. As for the main extensions that have worked well in Web Api, they have not been added to the pipeline vNext at the moment. As for example, a mechanism for determining the formatter by using Content Negotiation services. If an instance of a class that does not implement IActionResult is returned from a controller action, a JSON formatter is used.

    The application configuration mechanism has been greatly modified due to the transition to an updated project template. Now, instead of the old web.config, config.json is used, which represents the hierarchical structure of key-value pairs.

    Directly at the code level, a set of utilities is provided from the Microsoft.Framework.ConfigurationModel namespace, which merges keys from various configuration sources, for example, host application startup parameters passed to the K console; pairs defined in the project.json, config.json files of the web application.

    About each of the components, as well as those that were not mentioned, you can write a separate review and for sure it will not be alone. Given that the list of functional components of the new framework has not yet been finalized, we restrict ourselves to a basic understanding of the operation of its main components.


    After getting acquainted with the alpha version of ASP.NET MVC vNext, we can really say that the changes of the developers expect quite dramatic. They are associated not only with thorough ASP.NET refactoring, but also with the adaptation of the framework for the updated Runtime.

    At the application level, changing internal concepts is quite limited and will be intuitive for developers who have dealt with OWIN and previous versions of ASP.NET MVC.

    From the point of view of the framework itself, the most important is the transition to an open web interface and a clear delineation of responsibility between the host and the web application. High-quality updating of the composition of abstractions and the addition of flexible expansion options open up new prospects for the development of web applications.

    Useful resources:
    www.asp .net / aspnet / overview / owin-and-katana

    Also popular now: