قالب ASP.NET Core و Angular 2 برای Visual Studio
مراحل تنظیم Let's Encrypt در IIS
website -> SSL Settings -> Client Certificates -> Select `Ignore`: This is the default option.
طراحی یک ماژول IpBlocker در ASP.NET MVC
در قسمت بعد، قالب را هم از نوع empty انتخاب مینماییم.
در ادامه فایل project.json را باز کرده و در قسمت dependencies، تغییرات زیر را اعمال نمایید.
قبل از اینکه شما را از این همه وابستگی نگران کنم، باید عرض کنم فقط Microsoft.Owin , Microsoft.AspNetCore.Owin، پکیجهای اجباری هستند؛ باقی آنها برای نشان دادن انعطاف پذیری بالای این روش میباشند:
"dependencies": { "Microsoft.AspNet.OData": "5.9.1", "Microsoft.AspNet.SignalR": "2.2.1", "Microsoft.AspNet.WebApi.Client": "5.2.3", "Microsoft.AspNet.WebApi.Core": "5.2.3", "Microsoft.AspNet.WebApi.Owin": "5.2.3", "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Hosting": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", "Microsoft.AspNetCore.Owin": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Net.Http": "2.2.29", "Microsoft.Owin": "3.0.1", "Microsoft.Owin.Diagnostics": "3.0.1", "Microsoft.Owin.FileSystems": "3.0.1", "Microsoft.Owin.StaticFiles": "3.0.1", "Newtonsoft.Json": "9.0.1" }, //etc...
بعد از ذخیره کردن این فایل، در پنجرهی Output خود شاهد دانلود شدن این پکیجها خواهید بود. در اینجا پکیجهای مربوط به Owin, Odata, SignalR را مشاهد میکنید. ضمن اینکه در کنار آن، AspNetCore.Mvc را نیز مشاهده میفرمایید. دلیل این کار این است که این دو نوع متفاوت قرار است در کنار هم کار کنند و هیچ مشکلی با دیگری ندارند.
در مسیر اصلی پروژهی خود کلاسی به نام OwinExtensions را با محتوای زیر بسازید:
namespace OwinCore { public static class OwinExtensions { public static IApplicationBuilder UseOwinApp( this IApplicationBuilder aspNetCoreApp, Action<IAppBuilder> configuration) { return aspNetCoreApp.UseOwin(setup => setup(next => { AppBuilder owinAppBuilder = new AppBuilder(); IApplicationLifetime aspNetCoreLifetime = (IApplicationLifetime)aspNetCoreApp.ApplicationServices.GetService(typeof(IApplicationLifetime)); AppProperties owinAppProperties = new AppProperties(owinAppBuilder.Properties); owinAppProperties.OnAppDisposing = aspNetCoreLifetime?.ApplicationStopping ?? CancellationToken.None; owinAppProperties.DefaultApp = next; configuration(owinAppBuilder); return owinAppBuilder.Build<Func<IDictionary<string, object>, Task>>(); })); } } }
یک Extension Method به نام UseOwinApp اضافه شده به IApplicationBuilder که مربوط به ASP.NET Core میباشد و درون آن نیز AppBuilder را که مربوط به Owin pipeline میباشد، نمونه سازی کردهایم که باعث میشود Owin pipeline بر روی ASP.NET Core pipeline سوار شود.
حال میخواهیم یک Middleware سفارشی را با استفاده از Owin نوشته و در Startup پروژه، آن را فراخوانی نماییم. کلاسی به نام AddSampleHeaderToResponseHeadersOwinMiddleware را با محتوای زیر تولید مینماییم:
namespace OwinCore { public class AddSampleHeaderToResponseHeadersOwinMiddleware : OwinMiddleware { public AddSampleHeaderToResponseHeadersOwinMiddleware(OwinMiddleware next) : base(next) { } public async override Task Invoke(IOwinContext context) { //throw new InvalidOperationException("ErrorTest"); context.Response.Headers.Add("Test", new[] { context.Request.Uri.ToString() }); await Next.Invoke(context); } } }
کلاسی است که از owinMiddleware ارث بری کرده و در متد override شدهی Invoke نیز با استفاده از IOwinContext، به پیاده سازی Middleware خود میپردازیم. Exception مربوطه را comment کرده (بعدا در مرحلهی تست از آن نیز استفاده مینماییم) و در خط بعدی در هدر response هر request، یک شیء را به نام Test و با مقدار Uri آن request، میسازیم.
خط بعدی هم اعلام میدارد که به Middleware بعدی برود.
در ادامه فایل Startup.cs را باز کرده و اینگونه متد Configure را تغییر دهید:
public void Configure(IApplicationBuilder aspNetCoreApp, IHostingEnvironment env) { aspNetCoreApp.UseOwinApp(owinApp => { if (env.IsDevelopment()) { owinApp.UseErrorPage(new ErrorPageOptions() { ShowCookies = true, ShowEnvironment = true, ShowExceptionDetails = true, ShowHeaders = true, ShowQuery = true, ShowSourceCode = true }); } owinApp.Use<AddSampleHeaderToResponseHeadersOwinMiddleware>(); }); }
مشاهده میفرمایید با استفاده از UserOwinApp میتوانیم Middlewareهای Owinی خود را register نماییم و نکتهی قابل توجه این است که در کنار آن نیز میتوانیم از IHostingEnviroment مربوط به ASP.NET core استفاده نماییم. owinApp.UseErrorPage از Microsoft.Owin.Diagnostics گرفته شده است و در خط بعدی نیز Middleware شخصی خود را register کردهایم. پروژه را run کرده و در response این را مشاهد مینمایید.
اکنون اگر در Middleware سفارشی خود، آن Exception را از حالت comment در بیاوریم، در صورتیکه در حالت development باشیم، با این صفحه مواجه خواهیم شد:
Exception مربوطه را به حالت comment گذاشته و ادامه میدهیم.
برای اینکه نشان دهیم Owin و ASP.NET Core pipeline در کنار هم میتوانند کار کنند، یک Middleware را از نوع ASP.NET Core نوشته و آن را register مینماییم. کلاسی جدیدی را به نام AddSampleHeaderToResponseHeadersAspNetCoreMiddlware با محتوای زیر میسازیم:
namespace OwinCore { public class AddSampleHeaderToResponseHeadersAspNetCoreMiddlware { private readonly RequestDelegate Next; public AddSampleHeaderToResponseHeadersAspNetCoreMiddlware(RequestDelegate next) { Next = next; } public async Task Invoke(HttpContext context) { //throw new InvalidOperationException("ErrorTest"); context.Response.Headers.Add("Test2", new[] { "some text" }); await Next.Invoke(context); } } }
متد Configure در Startup.cs را نیز اینگونه تغییر میدهیم
public void Configure(IApplicationBuilder aspNetCoreApp, IHostingEnvironment env) { aspNetCoreApp.UseOwinApp(owinApp => { if (env.IsDevelopment()) { owinApp.UseErrorPage(new ErrorPageOptions() { ShowCookies = true, ShowEnvironment = true, ShowExceptionDetails = true, ShowHeaders = true, ShowQuery = true, ShowSourceCode = true }); } owinApp.Use<AddSampleHeaderToResponseHeadersOwinMiddleware>(); }); aspNetCoreApp.UseMiddleware<AddSampleHeaderToResponseHeadersAspNetCoreMiddlware>(); }
اکنون AddSampleHeaderToResponseHeadersAspNetCoreMiddlware رجیستر شده است و بعد از run کردن پروژه و بررسی header response باید این را ببینیم
میبینید که به ترتیب اجرای Middlewareها، ابتدا Test مربوط به Owin و بعد آن Test2 مربوط به ASP.NET Core تولید شده است.
حال اجازه دهید Odata را با استفاده از Owin پیاده سازی نماییم. ابتدا کلاسی را به نام Product با محتوای زیر تولید نمایید:
namespace OwinCore { public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } }
حال کلاسی را به نام ProductsController با محتوای زیر میسازیم:
namespace OwinCore { public class ProductsController : ODataController { [EnableQuery] public IQueryable<Product> Get() { return new List<Product> { new Product { Id = 1, Name = "Test" , Price = 10 } } .AsQueryable(); } } }
اگر مقالهی پیاده سازی Crud با استفاده از OData را مطالعه کرده باشید، قاعدتا با این کدها آشنا خواهید بود. ضمن اینکه پرواضح است که OData هیچ وابستگی به entity framework ندارد.
برای config آن نیز در Startup.cs پروژه و متد Configure، تغییرات زیر را اعمال مینماییم.
public void Configure(IApplicationBuilder aspNetCoreApp, IHostingEnvironment env) { //aspNetCoreApp.UseMvc(); aspNetCoreApp.UseOwinApp(owinApp => { if (env.IsDevelopment()) { owinApp.UseErrorPage(new ErrorPageOptions() { ShowCookies = true, ShowEnvironment = true, ShowExceptionDetails = true, ShowHeaders = true, ShowQuery = true, ShowSourceCode = true }); } // owinApp.UseFileServer(); as like as asp.net core static files middleware // owinApp.UseStaticFiles(); as like as asp.net core static files middleware // owinApp.UseWebApi(); asp.net web api / odata / web hooks HttpConfiguration webApiConfig = new HttpConfiguration(); ODataModelBuilder odataMetadataBuilder = new ODataConventionModelBuilder(); odataMetadataBuilder.EntitySet<Product>("Products"); webApiConfig.MapODataServiceRoute( routeName: "ODataRoute", routePrefix: "odata", model: odataMetadataBuilder.GetEdmModel()); owinApp.UseWebApi(webApiConfig); owinApp.MapSignalR(); //owinApp.Use<AddSampleHeaderToResponseHeadersOwinMiddleware>(); }); //aspNetCoreApp.UseMiddleware<AddSampleHeaderToResponseHeadersAspNetCoreMiddlware>(); }
برای config مخصوص Odata، به HttpConfiguration نیاز داریم. بنابراین instanceی از آن گرفته و برای مسیریابی Odata از آن استفاده مینماییم.
با استفاده از پیاده سازی که از استاندارد Owin انجام دادیم، مشاهده کردید که Odata را همانند یک پروژهی معمولی asp.netی، config نمودیم. در خط بعدی هم SignalR را مشاهده مینمایید.
اکنون اگر آدرس زیر را در مرورگر خود وارد نمایید، پاسخ زیر را از Odata دریافت خواهید کرد:
http://localhost:YourPort/odata/Products
بعد از فرستادن request فوق، باید response زیر را دریافت نمایید:
{ "@odata.context":"http://localhost:4675/odata/$metadata#Products","value":[ { "Id":1,"Name":"Test","Price":10 } ] }
تعداد زیادی Owin Middleware موجود همانند Thinktecture IdentityServer, NWebSec, Nancy, Facebook OAuth , ... هم با همان آموزش راه اندازی بر روی Owin که دارند میتوانند در ASP.NET Core نیز استفاده شوند و زمانی که نسخهی ASP.NET Core اینها به آمادگی کامل رسید، با کمترین تغییری میتوان از آنها استفاده نمود.