ارتقاء به ASP.NET Core 3.0
همانطور که پیشتر نیز اعلام شده بود، از نگارش 3، دیگر بستهی Microsoft.AspNetCore.All تولید نخواهد شد و اگر هنوز از آن استفاده میکنید باید از بستهی Microsoft.AspNetCore.App بجای آن استفاده نمائید.
نظرات مطالب
استفاده از Awesomium.NET در برنامههای وب
از cefSharp استفاده کنید که به روزتر است و مدام هم پشتیبانی میشود.
- بستهی نیوگت تهیه تصاویر از صفحات وب آن
- یک مثال نحوهی کاربرد این بستهی نیوگت
- بستهی نیوگت تهیه تصاویر از صفحات وب آن
- یک مثال نحوهی کاربرد این بستهی نیوگت
یک نکتهی تکمیلی: تزریق وابستگیها در حالتیکه از یک اینترفیس چندین کلاس مشتق شدهاند
نمونهی این نکته را پیشتر با Structure Map ملاحظه کرده بودید. پیاده سازی آن با امکانات توکار تزریق وابستگیهای NET Core. یا بر اساس روش Factory است که در نکتهی قبل ملاحظه میکنید و یا اگر از یک اینترفیس چندین پیاده سازی در برنامه وجود داشته باشند و ارتباطات آنها در ابتدای کار برنامه به سیستم توکار تزریق وابستگیهای NET Core. معرفی شده باشند، فقط کافی است یک <IEnumerable<IMultiple را به سازندهی کلاس سرویس استفاده کننده تزریق کنیم:
این IEnumerable لیست تمام وهلههای از این نوع را در اختیار سرویس جاری قرار میدهد. در این حالت دیگر نیازی به استفاده از factoryها نیست.
مرحلهی بعد، تشخیص و یا انتخاب یک پیاده سازی خاص است. الان لیستی از وهلههای تزریق شده را در اختیار داریم؛ اما میخواهیم فقط از یکی از آنها استفاده کنیم:
الف) انتخاب سرویس مدنظر بر اساس نوع کلاسی خاص
ب) نامدار کردن وهلهی مدنظر
این روشی است که برای مثال در Structure Map هم استفاده میشود (تحت عنوان named instances). یک خاصیت Name را به اینترفیسی که چندین پیاده سازی دارد، اضافه کنید. سپس بر اساس این Name کوئری بگیرید:
نمونهی این نکته را پیشتر با Structure Map ملاحظه کرده بودید. پیاده سازی آن با امکانات توکار تزریق وابستگیهای NET Core. یا بر اساس روش Factory است که در نکتهی قبل ملاحظه میکنید و یا اگر از یک اینترفیس چندین پیاده سازی در برنامه وجود داشته باشند و ارتباطات آنها در ابتدای کار برنامه به سیستم توکار تزریق وابستگیهای NET Core. معرفی شده باشند، فقط کافی است یک <IEnumerable<IMultiple را به سازندهی کلاس سرویس استفاده کننده تزریق کنیم:
private readonly IEnumerable<IMultiple> _services; public HomeController (IEnumerable<IMultiple> services) { _services = services; }
مرحلهی بعد، تشخیص و یا انتخاب یک پیاده سازی خاص است. الان لیستی از وهلههای تزریق شده را در اختیار داریم؛ اما میخواهیم فقط از یکی از آنها استفاده کنیم:
الف) انتخاب سرویس مدنظر بر اساس نوع کلاسی خاص
var serviceA = services.First(o => o.GetType() == typeof(ImplementationOne));
این روشی است که برای مثال در Structure Map هم استفاده میشود (تحت عنوان named instances). یک خاصیت Name را به اینترفیسی که چندین پیاده سازی دارد، اضافه کنید. سپس بر اساس این Name کوئری بگیرید:
var serviceB = services.First(o => o.Name.Equals("MyClassName"));
همانطور که میدانید وب سایتهای اینترنتی در معرض انواع و اقسام حملات قرار دارند و یکی از این حملات Dos است. در این نوشتار میخواهیم تکه کدی را ارائه دهیم، تا این نوع حملات را دفع نماید. همانطور که میدانید یک درخواست Http باید از ماژولهای مختلفی عبور نماید تا به یک Http Handler برسد.
ابتدا باید یک Enum تعریف کنیم تا نوع درخواست کاربر را مشخص کند. مثلا 100 درخواست ابتدایی را به عنوان FirstVisite در نظر گرفته و اگر تعداد درخواستها از 100 گذشت، در دسته Revisit قرار میگیرند و ... . البته این بستگی به شما دارد که مقادیر را چقدر در نظر بگیرید؛ اما دقت کنید.
private enum VisiteType { FirstVisite = 2, Reviste = 4, }
در مرحله بعدی باید آدرس Ip بیننده سایت را بدست آورده وچک کنیم که این آدرس Ip در کش موجود هست یا خیر. اگر موجود بود مقدار متغیر hits را افزایش میدهیم و چک میکنیم که متغیر با کدام یک از مقادیر Enum برابری میکند و آن را در کش سیستم ذخیره میکنیم.
if (httpContext.Cache[ipAddress] != null) { hits++; if (hits == (int)VisiteType.FirstVisite) { httpContext.Cache.Insert(key: ipAddress, value: hits, dependencies: null, absoluteExpiration: DateTime.UtcNow.AddSeconds(1), slidingExpiration: Cache.NoSlidingExpiration); return; }
در تکه کد بالا چون درخواست به حد معین و معقولی رسیده است، آدرس بعد از یک ثانیه از کش حذف میشود. اما اگر درخواستهای غیرمعقولی به سرور ارسال شود، باید پاسخ را قطع و آدرس Ip را در کش ذخیره و این آدرس Ip باید به مدت معینی در کش مانده و بلاک شود.
using System; using System.Net; using System.Web; using System.Web.Caching; namespace IpBlocker { public class IpBlocker : IHttpModule { private int hits = 0; /// <summary> /// Define enum to specify visite type /// </summary> private enum VisiteType { FirstVisite = 2, Reviste = 4, } public void Init(HttpApplication context) { context.BeginRequest += OnBeginRequest; } public void Dispose() { } public void OnBeginRequest(object sender, EventArgs e) { var httpApplication = sender as HttpApplication; var httpContext = httpApplication?.Context; ProcessRequest(httpApplication, httpContext); } private void ProcessRequest(HttpApplication application, HttpContext httpContext) { //Checke if browser is a search engine web crawler if (httpContext.Request.Browser.Crawler) return; var ipAddress = application.Context.Request.UserHostAddress; if (httpContext.Cache[ipAddress] == null) { // Reset hits for new request after blocking ip if (hits > 0) hits = 0; hits++; httpContext.Cache.Insert(key: ipAddress, value: hits, dependencies: null, absoluteExpiration: DateTime.UtcNow.AddSeconds(1), slidingExpiration: Cache.NoSlidingExpiration); return; } else { if (httpContext.Cache[ipAddress] != null) { hits++; if (hits == (int)VisiteType.FirstVisite) { httpContext.Cache.Insert(key: ipAddress, value: hits, dependencies: null, absoluteExpiration: DateTime.UtcNow.AddSeconds(1), slidingExpiration: Cache.NoSlidingExpiration); return; } if (hits == (int)VisiteType.Reviste) { httpContext.Cache.Insert(key: ipAddress, value: hits, dependencies: null, absoluteExpiration: DateTime.UtcNow.AddSeconds(1), slidingExpiration: Cache.NoSlidingExpiration); return; } if (hits > (int)VisiteType.Reviste) { httpContext.Cache.Insert(key: ipAddress, value: hits, dependencies: null, absoluteExpiration: DateTime.UtcNow.AddMinutes(1), slidingExpiration: Cache.NoSlidingExpiration); httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; httpContext.Response.SuppressContent = true; httpContext.Response.End(); } } } } } }
در کد بالا محدودیت زمانی یک دقیقه در نظر گرفته شده است.
اشتراکها
Microsoft.Data.Sqlite 5.0 منتشر شد
Microsoft.Data.Sqlite 5.0 is available now on NuGet. Update today and let me know if you run into any issues.
An alternative query compiler for Microsoft.EntityFrameworkCore.SqlServer that supports complex queries and operators and FOR JSON.
برای انتقال جداول احراز هویت (Identity) از SQL Server به بانک اطلاعاتی MongoDB و نحوه استفاده از آن از سورس نمونه در لینک بالا استفاده کنید.
همچنین در این پروژه از پکیج AspNet.Identity.MongoDB 2.0.8 که بر روی Nuget قرار دارد استفاده شده است.