Sharp katana.
Read Catalogue
- Development History of ASP
- Into the world of katana
- Using Asp.net/iis to host katana-based applications
- Using custom Host (self-host) to host katana-based applications
- Using OwinHost.exe to host katana-based applications
- Several methods for specifying startup items
- Advanced app for startup item startup
- Summary
正如上篇文章所述那样,OWIN在Web Server与Web Application之间定义了一套规范(Specs),意在解耦Web Server与Web Application,从而推进跨平台的实现。若要真正使用OWIN规范,那么必须要对他们进行实现。目前有两个产品实现了OWIN规范——由微软主导的Katana和第三方的Nowin。这篇文章,我主要关注还是Katana,由微软团队主导,开源到CodePlex上。可以在Visual Studio中输入命令:git clone https://git01.codeplex.com/katanaproject来查看源代码。
在介绍Katana之前,我觉得有必要为大家梳理一下过去10几年前ASP.NET 发展历程。
Back to the top of ASP. ASP. NET Web Form
When ASP. NET Web Form was officially released in 2002, there were two main types of developers:
- ASP developers using hybrid HTML markup and server-side scripting to develop dynamic Web sites, in addition, the ASP Runtime abstracts the underlying HTTP connection and Web Server, and provides developers with a range of object models for interactive HTTP requests, and of course, additional services such as session, Cache, state, and so on.
- Programmers who develop WinForm may have no knowledge of HTTP and HTML, but are familiar with the way to drag controls to build applications.
To cater to these two types of developers, the ASP. NET Web form uses a heavy viewstate to hold the state value of the page callback, because the HTTP protocol is stateless, and by ViewState, the HTTP protocol without memory becomes remembered. It was a very good design at the time, and it was possible to develop the web quickly in the form of drag-and-drop controls without having to focus too much on underlying principles. The ASP also enriched more features for ASP, such as: Session, Cache, configuration, and so on.
This was undoubtedly successful at the time, ASP. NET's release quickly courted developers, creating a new force in web development, but also buying some hidden dangers:
- All functions and features are posted on a monolithic framework and tightly coupled to the core of the Web Abstraction library--system.web
- System.Web is an important part of the. NET Framework, which means that to fix the update system.web the. NET Framework must be updated, but the. NET Framework is the basis of the operating system and is often not updated frequently for stability.
- The ASP. NET Framework (system.web) tightly coupled IIS
- IIS can only run on Windows systems
ASP. NET MVC
Because Web Form generates a large heap of viewstate and client-side scripting, this is slowly becoming a nuisance to developers because we only want to produce pure HTML markup. So developers want to actively control rather than passively generate extra HTML markup.
So Microsoft has introduced its important web framework--asp.net MVC Framework based on MVC design patterns, decoupling business logic and presentation logic through Model-view-control, without server-side controls, The control of the page is completely given to the developer.
To quickly update iterations and get updates through nuget, it is decoupled from the. NET framework.
But the only disadvantage is that ASP. NET MVC is still based on the ASP (Note: ASP. NET MVC 6 is no longer dependent on system.web), so Web application and Web server are still not decoupled.
ASP. NET Web API
As time went on, some problems began to emerge, and as Web server and Web application tightly coupled, Microsoft was stretched to the point of developing an independent, simple framework that contrasts with the booming of open source communities under other platforms, and fortunately, Microsoft has made a change by launching a standalone web Framework--asp.net Web API that works for the mobile internet and can be installed quickly through NuGet, and more importantly, He does not rely on system.web, and does not rely on IIS, you can self-host or deploy in other WEB servers.
Katana
As Web APIs run in their own lightweight hosts, and more and more simple, modular, and single-minded frameworks emerge, developers sometimes have to start separate processes to handle the various components (modules) of a WEB application, such as static files, dynamic files, web APIs and sockets. To avoid process proliferation, all processes must be started, stopped, and managed independently. at this point, we need a common hosting process to manage these modules.
This is why Owin was born, decoupled into a minimum-granularity component , and these standardized frameworks and components can be easily inserted into the Owin pipeline to manage the components in a unified manner. And Katana is the realization of Owin, providing us with a wealth of host and server.
Back to the top into the world of katana
Katana as a specification implementation of Owin, in addition to implementing host and server, also provides a series of APIs to help develop the application, which already includes some functional components such as authentication (authentication), diagnostics (diagnostics), Bindings for static file processing (static files), ASP. NET Web API, and SIGNALR.
The basic principles of katana
- Portability: From Hostàserveràmiddleware, the components in each pipeline are replaceable, and the framework of the third-party and open-source projects can be run on Owin server, that is, platform-limited, to achieve cross-platform.
- Modularity: Each component must remain sufficiently independent, usually doing only one thing, in the form of a mixed module to meet the actual development needs
- Lightweight and efficient: Because each component is modular, it is easy to plug and unplug components in the pipeline for efficient development
Katana Architecture
Katana implements the Owin layers, so katana's architecture and Owin are consistent as follows:
1.) Host: The host host is defined by the Owin specification on the first layer (bottom level), his responsibility is to manage the underlying process (start, shut down), initialize the Owin Pipeline, select the server run, and so on.
Katana offers us a choice of 3:
- Iis/asp.net: Using IIS is the simplest and backwards compatible way in which Owin pipeline is started by standard HttpModule and HttpHandler. Using this host you must use System.Web as the Owin Server
- Custom Host: If you want to use a different server to replace system.web, and you can have more control, you can choose to create a custom host, such as using Windows Service, console applications, WinForm to host the server.
- Owinhost: If you are not satisfied with the above two hosts, the last option is to use the OwinHost.exe provided by Katana: He is a command-line application that runs at the root of the project and starts HttpListener Server and locate the constraint-based startup startup item. Owinhost provides command-line options to customize his behavior, such as manually specifying a startup startup item or using a different server (if you don't need the default HttpListener server).
2.) Server
The layer after host is called Server, and he is responsible for opening the socket and listening for HTTP requests, and once the request arrives, build the environment Dictionary (Environment dictionary) according to the HTTP request that conforms to the Owin specification. and send it to the pipeline to be processed by middleware. Katana implementation of Owin server is divided into the following categories:
- System.Web: As mentioned earlier, system.web and iis/asp.net host are coupled to each other when you choose to use system.web as Server,katana system.web The server registers itself as HttpModule and httpserver and processes the request sent to IIS, and finally maps the HttpRequest, HttpResponse object to the Owin environment dictionary and sends it to pipeline for processing.
- HttpListener: This is the OwinHost.exe and the custom host default server.
- Weblistener: This is the default lightweight server for ASP. Vnext, which he is currently unable to use in Katana
3) Middleware
Middleware (middleware) is located after host, server, to handle requests in pipeline, middleware can be understood to implement Owin application delegated appfun components.
The middleware processes the request and can be processed by the middleware component in the next pipeline, which is a chained processing request, which allows all HTTP request data and custom data to be obtained through the Environment dictionary. Middleware can be a simple log component, or a complex large web Framework, such as the ASP. NET Web API, Nancy, SIGNLR, and so on, as shown in: Pipeline in middleware to handle requests:
4.) Application
The last layer is the application, which is the implementation of the specific code, such as ASP. NET Web API, signalr specific code.
Now, I think you should know something about katana and the basic principles and architecture of katana, so now is the concrete application to the actual.
Back to top using Asp.net/iis hosted katana-based application
- Visual Studio creates a Web application
- Install-package Microsoft.Owin.Host.SystemWeb Add Startup Startup class
- Asp.net/iis as host
- System.Web as Server
Implement the Owin pipeline processing logic in the startup configuration method, as shown in the following code:
- public class startup
- {
- public void configuration (Iappbuilder app)
- {
- app. Run (context =>
- {
- context. Response.ContentType = "Text/plain";
- return context. Response.writeasync ("Hello World");
- });
- }
- }
App. The Run method takes a lambda expression that takes the most input parameter of the Iowincontext object and returns the task as the last processing step of the Owin pipeline, Iowincontext the strongly typed object is the environment Dictionary the package, and then asynchronously outputs the "Hello World" string.
Careful you may observe that When NuGet installs the Microsoft.Owin.Host.SystemWeb assembly, the dependency Microsoft.owin assembly is installed by default, formally giving us the extension method run and the Iowincontext interface, and of course we can use the most primitive way to output The "Hello World" string, the Owin assembly, provides us with the most primitive way, which is only a learning reference, although we will not use it in a formal scenario:
- Using Appfunc = func<idictionary<string, object>, task>;
- public class Startup
- {
- public void Configuration (Iappbuilder app)
- {
- App. Use (New Func<appfunc, appfunc> (next =
- {
- String text = "Hello World";
- var response = env["Owin. Responsebody "] as Stream;
- var headers = env["Owin. Responseheaders "] as idictionary<string, string[]>;
- headers["Content-type"] = new[] {"Text/plain"};
- return response. WriteAsync (Encoding.UTF8.GetBytes (text), 0, text. Length);
- })));
- }
- }
Back to top using a custom host (self-host) managed katana-based application
Using custom host-hosted Katana applications is not very different from using IIS hosting, but you can use consoles, WinForm, WPF, and so on for hosting, but remember that this loses some of the features that IIS has (SSL, Event Log, diagnostics, Management ... ), of course, this can be achieved by themselves.
- To create a console application
- Install-package Microsoft.Owin.SelfHost
- Building pipeline and listening ports using the startup configuration item in the Main method
- static void Main (string[] args)
- {
- using (webapp.start<startup> ("http://localhost:10002"))
- {
- System.Console.WriteLine ("Start site: http://localhost:10002");
- System.Console.ReadLine ();
- }
- }
Using a custom host will lose some of the functionality of IIS, and of course we can implement it ourselves. Fortunately, Katana has implemented some features for us by default, such as diagnostic, which is included in the Assembly Microsoft.Owin.Diagnostic.
- public void Configuration (Iappbuilder app)
- {
- App. Usewelcomepage ("/");
- App. Useerrorpage ();
- App. Run (context =
- {
- Log requests to the console
- Trace.WriteLine (context. Request.uri);
- Display error page
- if (context. Request.Path.ToString (). Equals ("/error"))
- {
- throw new Exception ("throw exception");
- }
- Context. Response.ContentType = "Text/plain";
- Return to context. Response.writeasync ("Hello World");
- });
- }
In the preceding code, when the requested path (Request.path) is the root, the rendered output webcome the Page and does not continue to execute the remaining middleware components in pipeline , as follows:
If the requested path is error, an exception is thrown and the error page is displayed as follows:
Back to top using OwinHost.exe hosted katana-based application
Of course we can also use the OwinHost.exe provided by Katana to host the application, without a doubt installing owinhost through NuGet.
If you follow my example, you will find that the startup configuration class is immutable regardless of whether you use Asp.net/iis hosting or self-hosting, and only the managed mode is changed. The same is true for owinhost, but it is more flexible and we can use class libraries or Web applications as application.
- Working with class libraries
Class Library as application, you can minimize the reference to the assembly, create a class library, delete the default Class1.cs, and then add a startup startup item, which defaults to adding references to Owin and Microsoft.owin assemblies like the class library.
Then, using NuGet to install OwinHost.exe, such as Install-package owinhost, note that it is not an assembly, but that the. exe application is located in <solution root>/packages/ Owinhost. (version)/tools folder.
Because the class library cannot be run directly, it can only be managed at its root by calling OwinHost.exe, which will load all the assemblies under the. \ bin file, so you need to change the default output of the class library as follows:
Then compile the solution, open cmd, and type the following command:
If host host is successfully booted and 5000 ports are listening by default.
OwinHost.exe also provides custom parameters to view by appending-H, as shown below:
Since the class library cannot be run directly, and of course you cannot debug directly, we can attach the owinhost process for debugging as follows:
Note:
When I use OwinHost.exe 3.0.1 , startup if it is under the following circumstances, it prompts the conversion to fail, I do not know whether it is the version of the bug.
- Using Appfunc = func<idictionary<string, object>, task>;
- public class Startup
- {
- public void Configuration (Iappbuilder app)
- {
- Use OwinHost.exe, error, prompt conversion failed
- App. Run (Context=>context. Response.writeasync ("Hello World");
- Use OwinHost.exe without error
- App. Use (New Func<appfunc, appfunc> (next =
- //{
- String text = "Hello World";
- var response = env["Owin. Responsebody "] as Stream;
- var headers = env["Owin. Responseheaders "] as idictionary<string, string[]>;
- headers["Content-type"] = new[] {"Text/plain"};
- return response. WriteAsync (Encoding.UTF8.GetBytes (text), 0, text. Length);
- //})));
- }
- }
The error message is as follows:
- Using the Web application
The WEB application is much easier to use than a class library, you can run and debug directly, the only weaker is that it references more assemblies, you can completely delete, such as system.web.
After installing OwinHost.exe with NuGet, you can use it in the Web as follows:
Back to top several methods for specifying startup items
- Default name constraint: By default, host will look for a class named startup under Root namespace as the startup item.
- Owinstartup Attribute: When the Owin startup class is created, it automatically adds Attribute such as:[Assembly:Owinstartup(typeof (jkxy. KatanaDemo.OwinHost.Startup)]
- Configuration files, such as: <add key= "Owin:appstartup" value= "Jkxy. KatanaDemo.Web.StartupDefault "/>
- If you use a custom host, you can set the startup item by Webapp.start<startup>("http://localhost:10002").
- If you use Owinhost, you can do so by command-line arguments, as shown below
Go back to top startup item startup's Advanced app
Startup item startup supports friendly name, via friendly name we can dynamically switch startup.
For example, in the deployment, we will have UAT environment, production environment, in different environments we can dynamically switch the startup to perform different operations.
For a chestnut, I created two startup with friendly name, as follows:
1 [Assembly:owinstartup ("Production", typeof (Jkxy. KatanaDemo.Web.StartupProduction)] 2 namespace Jkxy. Katanademo.web 3 {4 using Appfunc = func<idictionary<string, Object>, task>; 5 public class Startupp Roduction 6 {7 public void Configuration (Iappbuilder app) 8 {9 app. Run (Context=>context. Response.writeasync ("Production")); }11 }12}
1 [Assembly:owinstartup ("UAT", typeof (Jkxy. KatanaDemo.Web.StartupUAT)] 2 3 namespace Jkxy. Katanademo.web 4 {5 Public class Startupuat 6 {7 public void Configuration (Iappbuilder app) 8 {9
app. Run (Context=>context. Response.writeasync ("UAT")); }11 }12}
- Use the configuration file or the Owinhost parameter to switch startup according to friendly name
<appSettings> <add key= "Owin:appstartup" value= "Production"/> </appSettings>
Back to the top of the summary
Spent a long time to finally finish this blog, for everyone to explain the world of katana, then I will continue to Owin & Katana tour, explore the creation of middleware, thank you for your support.
Sharp katana.