Create C# project of Asp.net Core web application using fully .Net framework and name it “OwinCore”.
And in the next part select a template of Empty.
I don’t explain more in Asp.net Core and i assumed you have familiar with this framework before.
OK, now open “project.json” file to handle dependencies of this project.
Before I worry you to see lots of dependencies I should say that the main important package to use Owin are just “Microsoft.Owin” & “Microsoft.AspNetCore.Owin” and other packages are the just cause of show how this way is flexible and we can have different packages of different architecture together in a project.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="code-string">"</span><span class="code-string">dependencies"</span>: { <span class="code-string">"</span><span class="code-string">Microsoft.AspNet.OData"</span>: <span class="code-string">"</span><span class="code-string">5.9.1"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNet.SignalR"</span>: <span class="code-string">"</span><span class="code-string">2.2.1"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNet.WebApi.Client"</span>: <span class="code-string">"</span><span class="code-string">5.2.3"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNet.WebApi.Core"</span>: <span class="code-string">"</span><span class="code-string">5.2.3"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNet.WebApi.Owin"</span>: <span class="code-string">"</span><span class="code-string">5.2.3"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNetCore.Diagnostics"</span>: <span class="code-string">"</span><span class="code-string">1.0.0"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNetCore.Hosting"</span>: <span class="code-string">"</span><span class="code-string">1.0.0"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNetCore.Mvc"</span>: <span class="code-string">"</span><span class="code-string">1.0.0"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNetCore.Owin"</span>: <span class="code-string">"</span><span class="code-string">1.0.0"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNetCore.Server.IISIntegration"</span>: <span class="code-string">"</span><span class="code-string">1.0.0"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.AspNetCore.Server.Kestrel"</span>: <span class="code-string">"</span><span class="code-string">1.0.0"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.Extensions.Logging.Console"</span>: <span class="code-string">"</span><span class="code-string">1.0.0"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.Net.Http"</span>: <span class="code-string">"</span><span class="code-string">2.2.29"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.Owin"</span>: <span class="code-string">"</span><span class="code-string">3.0.1"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.Owin.Diagnostics"</span>: <span class="code-string">"</span><span class="code-string">3.0.1"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.Owin.FileSystems"</span>: <span class="code-string">"</span><span class="code-string">3.0.1"</span>, <span class="code-string">"</span><span class="code-string">Microsoft.Owin.StaticFiles"</span>: <span class="code-string">"</span><span class="code-string">3.0.1"</span>, <span class="code-string">"</span><span class="code-string">Newtonsoft.Json"</span>: <span class="code-string">"</span><span class="code-string">9.0.1"</span> }, <span class="code-comment">//</span><span class="code-comment">etc...</span> |
after saving this file you can see Output window to see downloaded files from NuGet package manager, you see OData, SignalR, Owin and beside those we have AspNetCore.Mvc. The reason for these two deferent type of package are going to work beside of together and don’t have any problems.
In the main of your project create a class named “OwinExtensions” with this content
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<span class="code-keyword">using</span> Microsoft.AspNetCore.Builder; <span class="code-keyword">using</span> Microsoft.AspNetCore.Hosting; <span class="code-keyword">using</span> Microsoft.Owin.Builder; <span class="code-keyword">using</span> Microsoft.Owin.BuilderProperties; <span class="code-keyword">using</span> Owin; <span class="code-keyword">using</span> System; <span class="code-keyword">using</span> System.Collections.Generic; <span class="code-keyword">using</span> System.Threading; <span class="code-keyword">using</span> System.Threading.Tasks; <span class="code-keyword">namespace</span> OwinCore { <span class="code-keyword">public</span> <span class="code-keyword">static</span> <span class="code-keyword">class</span> OwinExtensions { <span class="code-keyword">public</span> <span class="code-keyword">static</span> IApplicationBuilder UseOwinApp( <span class="code-keyword">this</span> IApplicationBuilder aspNetCoreApp, Action<IAppBuilder> configuration) { <span class="code-keyword">return</span> aspNetCoreApp.UseOwin(setup =<span class="code-keyword">></span> setup(next =<span class="code-keyword">></span> { AppBuilder owinAppBuilder = <span class="code-keyword">new</span> AppBuilder(); IApplicationLifetime aspNetCoreLifetime = (IApplicationLifetime)aspNetCoreApp.ApplicationServices.GetService(<span class="code-keyword">typeof</span>(IApplicationLifetime)); AppProperties owinAppProperties = <span class="code-keyword">new</span> AppProperties(owinAppBuilder.Properties); owinAppProperties.OnAppDisposing = aspNetCoreLifetime?.ApplicationStopping ?? CancellationToken.None; owinAppProperties.DefaultApp = next; configuration(owinAppBuilder); <span class="code-keyword">return</span> owinAppBuilder.Build<Func<IDictionary<string, object>, Task>>(); })); } } } |
An extension method named “UseOwinApp” added to IApplicationBuilder regarding Asp.net Core and inside that create an instance of AppBuilder regarding Owin pipeline that causes Owin pipeline will work beside of Asp Core pipeline.
Now we want to create custom Owin middleware and register that in Startup of application. create a class named “AddSampleHeaderToResponseHeadersOwinMiddleware ” with this content
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="code-keyword">using</span> Microsoft.Owin; <span class="code-keyword">using</span> System.Threading.Tasks; <span class="code-keyword">namespace</span> OwinCore { <span class="code-keyword">public</span> <span class="code-keyword">class</span> AddSampleHeaderToResponseHeadersOwinMiddleware : OwinMiddleware { <span class="code-keyword">public</span> AddSampleHeaderToResponseHeadersOwinMiddleware(OwinMiddleware next) : <span class="code-keyword">base</span>(next) { } <span class="code-keyword">public</span> <span class="code-keyword">async</span> <span class="code-keyword">override</span> Task Invoke(IOwinContext context) { <span class="code-comment">//</span><span class="code-comment">throw new InvalidOperationException("ErrorTest");</span> context.Response.Headers.Add(<span class="code-string">"</span><span class="code-string">Test"</span>, <span class="code-keyword">new</span>[] { context.Request.Uri.ToString() }); <span class="code-keyword">await</span> Next.Invoke(context); } } } |
It’s a class inherited from OwinMiddlewareand Invoke is an overridden method with IOwinContext and inside that we can implement our custom middleware.
I commented Exception cause we need it later, and in the next line, in a response of header of each request, it creates an object named “Test” with Uri value.
And next line says that you can go to the next middleware.
Now, open the “Startup.cs” and edit “Configure” method like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<span class="code-keyword">public</span> <span class="code-keyword">void</span> Configure(IApplicationBuilder aspNetCoreApp, IHostingEnvironment env) { aspNetCoreApp.UseOwinApp(owinApp =<span class="code-keyword">></span> { <span class="code-keyword">if</span> (env.IsDevelopment()) { owinApp.UseErrorPage(<span class="code-keyword">new</span> ErrorPageOptions() { ShowCookies = <span class="code-keyword">true</span>, ShowEnvironment = <span class="code-keyword">true</span>, ShowExceptionDetails = <span class="code-keyword">true</span>, ShowHeaders = <span class="code-keyword">true</span>, ShowQuery = <span class="code-keyword">true</span>, ShowSourceCode = <span class="code-keyword">true</span> }); } owinApp.Use<AddSampleHeaderToResponseHeadersOwinMiddleware>(); }); } |
By using UseOwinApp we can register owin middleware what remarkable is we have used owin middleware beside of IHostingEnviroment related on asp net core pipeline. owinApp.UseErrorPage has taken of Microsoft.Owin.Diagnostics, and in the next line we have registered our custom owin middleware.
Run the project and you should see this on response of your header of any request.
because of showing that Owin and Asp.net core pipeline can work beside together easily, we create a new custom asp.net core middleware and register that on “Configure” method.
create a new class named “AddSampleHeaderToResponseHeadersAspNetCoreMiddlware” with this content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="code-keyword">namespace</span> OwinCore { <span class="code-keyword">public</span> <span class="code-keyword">class</span> AddSampleHeaderToResponseHeadersAspNetCoreMiddlware { <span class="code-keyword">private</span> <span class="code-keyword">readonly</span> RequestDelegate Next; <span class="code-keyword">public</span> AddSampleHeaderToResponseHeadersAspNetCoreMiddlware(RequestDelegate next) { Next = next; } <span class="code-keyword">public</span> <span class="code-keyword">async</span> Task Invoke(HttpContext context) { <span class="code-comment">//</span><span class="code-comment">throw new InvalidOperationException("ErrorTest");</span> context.Response.Headers.Add(<span class="code-string">"</span><span class="code-string">Test2"</span>, <span class="code-keyword">new</span>[] { <span class="code-string">"</span><span class="code-string">some text"</span> }); <span class="code-keyword">await</span> Next.Invoke(context); } } } |
And in Configure method on Startup class, we have this changeset.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="code-keyword">public</span> <span class="code-keyword">void</span> Configure(IApplicationBuilder aspNetCoreApp, IHostingEnvironment env) { aspNetCoreApp.UseOwinApp(owinApp =<span class="code-keyword">></span> { <span class="code-keyword">if</span> (env.IsDevelopment()) { owinApp.UseErrorPage(<span class="code-keyword">new</span> ErrorPageOptions() { ShowCookies = <span class="code-keyword">true</span>, ShowEnvironment = <span class="code-keyword">true</span>, ShowExceptionDetails = <span class="code-keyword">true</span>, ShowHeaders = <span class="code-keyword">true</span>, ShowQuery = <span class="code-keyword">true</span>, ShowSourceCode = <span class="code-keyword">true</span> }); } owinApp.Use<AddSampleHeaderToResponseHeadersOwinMiddleware>(); }); aspNetCoreApp.UseMiddleware<AddSampleHeaderToResponseHeadersAspNetCoreMiddlware>(); } |
Now “AddSampleHeaderToResponseHeadersAspNetCoreMiddlware” middleware has been registered and you can see the result on response of header of nay request.
you see our middleware of different pipeline are working together and because Owin middleware has registered before Asp.net core middleware, they will be executed in the sequence of registered middleware.
“Test” has created by owin and “Test2” has created by asp net core.
Now I wanna implement OData protocol using owin pipeline in asp net core application.
First, create a class named “Product” like this.
1 2 3 4 5 6 7 8 9 |
<span class="code-keyword">namespace</span> OwinCore { <span class="code-keyword">public</span> <span class="code-keyword">class</span> Product { <span class="code-keyword">public</span> <span class="code-keyword">int</span> Id { <span class="code-keyword">get</span>; <span class="code-keyword">set</span>; } <span class="code-keyword">public</span> <span class="code-keyword">string</span> Name { <span class="code-keyword">get</span>; <span class="code-keyword">set</span>; } <span class="code-keyword">public</span> <span class="code-keyword">decimal</span> Price { <span class="code-keyword">get</span>; <span class="code-keyword">set</span>; } } } |
And now we create a class named “ProductsController” with this content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span class="code-keyword">namespace</span> OwinCore { <span class="code-keyword">public</span> <span class="code-keyword">class</span> ProductsController : ODataController { [EnableQuery] <span class="code-keyword">public</span> IQueryable<Product> Get() { <span class="code-keyword">return</span> <span class="code-keyword">new</span> List<Product> { <span class="code-keyword">new</span> Product { Id = <span class="code-digit">1</span>, Name = <span class="code-string">"</span><span class="code-string">Test"</span> , Price = <span class="code-digit">10</span> } } .AsQueryable(); } } } |
If you have familiar with OData protocol, you would know how this controller works but if not, it’s a simple OData controller using web api and Get function returns an IQueryable of Product and we can have filter on requested query using third party tools such as JayData or Breeze.
And it’s clear that OData is nuget related to entity framework!
OData config is incredibly easy and you can do that in Configure method like this way.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<span class="code-keyword">public</span> <span class="code-keyword">void</span> Configure(IApplicationBuilder aspNetCoreApp, IHostingEnvironment env) { <span class="code-comment">//</span><span class="code-comment">aspNetCoreApp.UseMvc();</span> aspNetCoreApp.UseOwinApp(owinApp =<span class="code-keyword">></span> { <span class="code-keyword">if</span> (env.IsDevelopment()) { owinApp.UseErrorPage(<span class="code-keyword">new</span> ErrorPageOptions() { ShowCookies = <span class="code-keyword">true</span>, ShowEnvironment = <span class="code-keyword">true</span>, ShowExceptionDetails = <span class="code-keyword">true</span>, ShowHeaders = <span class="code-keyword">true</span>, ShowQuery = <span class="code-keyword">true</span>, ShowSourceCode = <span class="code-keyword">true</span> }); } <span class="code-comment">//</span><span class="code-comment"> owinApp.UseFileServer(); as like as asp.net core file server middleware</span> <span class="code-comment">//</span><span class="code-comment"> owinApp.UseStaticFiles(); as like as asp.net core static files middleware</span> <span class="code-comment">//</span><span class="code-comment"> owinApp.UseWebApi(); asp.net web api / odata / web hooks</span> <span class="code-comment">//</span><span class="code-comment">OData config</span> HttpConfiguration webApiConfig = <span class="code-keyword">new</span> HttpConfiguration(); ODataModelBuilder odataMetadataBuilder = <span class="code-keyword">new</span> ODataConventionModelBuilder(); odataMetadataBuilder.EntitySet<Product>(<span class="code-string">"</span><span class="code-string">Products"</span>); webApiConfig.MapODataServiceRoute( routeName: <span class="code-string">"</span><span class="code-string">ODataRoute"</span>, routePrefix: <span class="code-string">"</span><span class="code-string">odata"</span>, model: odataMetadataBuilder.GetEdmModel()); owinApp.UseWebApi(webApiConfig); <span class="code-comment">//</span><span class="code-comment">End of OData config</span> owinApp.MapSignalR(); <span class="code-comment">//</span><span class="code-comment">owinApp.Use<AddSampleHeaderToResponseHeadersOwinMiddleware>();</span> }); <span class="code-comment">//</span><span class="code-comment">aspNetCoreApp.UseMiddleware<AddSampleHeaderToResponseHeadersAspNetCoreMiddlware>();</span> |
OData needs an instance of HttpConfiguration, using ODataModelBuilder we can add all needed EntitySet and using MapODataServiceRoute we can handle routing and if we have multiple OData endpoints we can have multiple routing easily with different routeName and routePrefix.
By using implementation of owin pipeline we could config OData easily such normal asp.net project and you can see you can config SignalR and other packages too.
Run the project and send this get request.
1 |
http:<span class="code-comment">//</span><span class="code-comment">localhost:YourPort/odata/Product</span> |
the response of this request should be something like below object.
1 2 3 4 5 6 7 |
{ <span class="code-string">"</span><span class="code-string">@odata.context"</span>:<span class="code-string">"</span><span class="code-string">http://localhost:4675/odata/$metadata#Products"</span>,<span class="code-string">"</span><span class="code-string">value"</span>:[ { <span class="code-string">"</span><span class="code-string">Id"</span>:<span class="code-digit">1</span>,<span class="code-string">"</span><span class="code-string">Name"</span>:<span class="code-string">"</span><span class="code-string">Test"</span>,<span class="code-string">"</span><span class="code-string">Price"</span>:<span class="code-digit">10</span> } ] } |
Lots of owin middlewares such as “Thinktecture IdentityServer”, “NWebSec”, “Facebook OAuth”,… can implement by this tutorial on asp net core applications by their owin configuration easily.
After preparing these packages on .net core edition we can use that easily without big code refactoring!
No #1 Recommended ASP.NET Core Hosting
ASPHostPortal.com
ASPHostPortal.com is the leading provider of Windows hosting and affordable ASP.NET MVC Hosting. ASPHostPortal proudly working to help grow the backbone of the Internet, the millions of individuals, families, micro-businesses, small business, and fledgling online businesses. ASPHostPortal has ability to support the latest Microsoft and ASP.NET technology, such as: WebMatrix, WebDeploy, Visual Studio 2015, .NET 5/ASP.NET 4.5.2, ASP.NET MVC 6.0/5.2, Silverlight 6 and Visual Studio Lightswitch, ASPHostPortal guarantees the highest quality product, top security, and unshakeable reliability, carefully chose high-quality servers, networking, and infrastructure equipment to ensure the utmost reliability.
HostForLIFE.eu
HostForLIFE.eu guarantees 99.9% uptime for their professional ASP.NET MVC hosting and actually implements the guarantee in practice. HostForLIFE.eu is the service are excellent and the features of the web hosting plan are even greater than many hosting. HostForLIFE.eu offer IT professionals more advanced features and the latest technology. Relibility, Stability and Performance of servers remain and TOP priority. Even basic service plans are equipped with standard service level agreements for 99.99% uptime. Advanced options raise the bar to 99.99%. HostForLIFE.eu revolutionized hosting with Plesk Control Panel, a Web-based interface that provides customers with 24×7 access to their server and site configuration tools.
DiscountService.com.au
DiscountService.com.au is The Best and Cheap ASP.NET MVC Hosting. DiscountService.com.au was established to cater to an under served market in the hosting industry web hosting for customers who want excellent service. DiscountService.com.au guarantees the highest quality product, top security, and unshakeable reliability, carefully chose high-quality servers, networking, and infrastructure equipment to ensure the utmost reliability. DiscountService.com.au has ability to support the latest Microsoft and ASP.NET technology, such as: WebMatrix, WebDeploy, Visual Studio 2015, .NET 5/ASP.NET 4.5.2, ASP.NET MVC 6.0/5.2, Silverlight 6 and Visual Studio Lightswitch. DiscountService.com.au is devoted to offering the best Windows hosting solution for you.