- متغیر Application مربوط هست به دوران Classics ASP دههی نود میلادی (حتی پیش از معرفی ASP.NET Web Forms). این متغیر این روزها با یک ConcurrentDictionary که بدون نیاز به قفل گذاری، امکان تهیه یک دیکشنری thread-safe را میسر میکند، قابلیت جایگزینی را دارد. یک مثال از کاربرد ConcurrentDictionary (OnlineVisitorsModule.zip برای ASP.NET 4.x و MVC 5.x)
- رویدادهای Session_Start و Session_End و کلا مباحث Global.asax در اصل بهتر است به HTTP Modules تبدیل و refactor شوند. HTTP Modules هم در ASP.NET Core به صورت کامل حذف و با مفهوم جدیدی به نام Middlewares جایگزین شدهاند. امکان نوشتن Middlewareهای سفارشی هم وجود دارد.
بررسی ASP.NET Core
If you stumble into this with no idea who I am or why I’m arrogant enough to think I’m qualified to potentially criticize the ASP.Net Core internals, I’m the primary author of both StructureMap (the IoC container) and an alternative “previous generation” OSS web development framework called FubuMVC that tackled a lot of the same problems that ASP.Net Core addresses now that were not part of older ASP.Net MVC or Web API.
مروری بر ASP.NET Core View Component
Partial Views and Child Actions are one the most used features of ASP.NET MVC. Partial Views provides us a way to create a reusable component that can be used in multiple Views. There are Actions which can be marked as Child Actions and these cannot be invoked via URL but inside views or partial views. Child Actions are no more available with ASP.NET Core. View Components are new way to implement this feature in ASP.NET Core.
ایجاد فیلتر برای هدایت همهی درخواستها به صفحهی «در حال بهروزرسانی» در برنامههای ASP.NET MVC
کدام نگارشهای NET Core. بر روی سیستم شما نصب هستند؟
پیش از انجام هرکاری نیاز است بررسی کنیم کدامیک از بستههای ارائه شده، بر روی سیستم جاری نصب هستند. برای انجام اینکار دستور زیر را در خط فرمان صادر کنید:
dotnet --info
Runtime تنها ویژگیهای اساسی جهت اجرای برنامههای از پیش کامپایل شدهی NET Core. را با اجرای فرمانی مانند dotnet mydll.dll و یا اجرای دستور dotnet --info برای دریافت اطلاعاتی از جزئیات این ویژگیها، به همراه دارد. اما برای کار با سورس کدها، build، publish و هر کار دیگری با آنها، حتما باید SDK نیز نصب شود.
خروجی فرمان فوق بر روی سیستم من چنین چیزی است:
C:\Users\Vahid>dotnet --info .NET Core SDK (reflecting any global.json): Version: 2.1.301 Commit: 59524873d6 Runtime Environment: OS Name: Windows OS Version: 10.0.17134 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\2.1.301\ Host (useful for support): Version: 2.1.1 Commit: 6985b9f684 .NET Core SDKs installed: 2.1.300 [C:\Program Files\dotnet\sdk] 2.1.301 [C:\Program Files\dotnet\sdk] .NET Core runtimes installed: Microsoft.NETCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download
باید دقت داشت که بر روی یک سیستم میتوان چندین SDK و چندین Runtime مختلف را نصب کرد و هر پروژه از شماره نگارش خاصی استفاده کند. شماره نگارش runtime استفاده شدهی در پروژهها در فایل csproj، توسط مدخل زیر مشخص میشود:
<TargetFramework>netcoreapp2.1</TargetFramework>
{ "sdk": { "version": "2.1.300-rc.31211" } }
البته در اکثر موارد نیازی به انجام این کار نیست؛ چون SDK، با تمام نگارشهای قبلی سازگار است و همواره استفادهی از آخرین SDK نصب شده توصیه میشود. به همین جهت فایل global.json را پس از ایجاد یک solution جدید مشاهده نمیکنید؛ مگر اینکه خودتان به دلایل خاصی آنرا اضافه و مقید نمائید.
تفاوت بستههای مختلف قابل دریافت NET Core. در چیست؟
زمانیکه برای دریافت آخرین نگارش NET Core. به سایت آن مراجعه میکنیم، به ازای هر نگارش، یک چنین لیستی قابل مشاهده است:
• .NET Core Runtime • .NET Core SDK • .NET Core Hosting Bundle • Visual Studio • ASP.NET Core Installer
Visual Studio
اگر کاربر ویندوز هستید، با نصب آخرین نگارش Visual Studio، میتوانید به همراه آن، آخرین نگارش SDK ،runtime و اجزای هاست برنامههای ASP.NET Core بر روی IIS را نیز بر روی سیستم خود نصب کنید.
NET Core SDK.
هدف از ارائهی بستهی SDK، انجام فرآیندهای build، اجرا و مدیریت امور مرتبط با NET Core.، بدون استفاده از Visual Studio و بر روی تمام سیستم عاملهای پشتیبانی شدهاست. زمانیکه یک بستهی SDK را نصب میکنید، به همراه آن این موارد نیز نصب میشوند:
• .NET Core SDK • .NET Core Runtime • ASP.NET Core Runtime
بنابراین دلیل نصب آن میتواند شامل یکی از موارد زیر باشد:
- بر روی سیستمی که در حال توسعهی برنامههای مبتنی بر NET Core. هستید. این تمام چیزی است که به آن نیاز دارید.
- بر روی سروری که نیاز است دستور dotnet را برای انجام فرآیندهای build/publish اجرا کند.
NET Core Runtime.
بستههای Runtimes، کوچکترین بستهی ممکن در این لیست هستند و هدف از آنها صرفا اجرای برنامههای کامپایل شدهی NET Core. در سکوهای کاری مختلف پشتیبانی شدهی توسط آن است.
باید دقت داشت که اگر برنامهی شما از «ASP.NET Core meta package» استفاده میکند، این بسته در runtime لحاظ نشدهاست و در یک چنین حالتی باید بستهی ASP.NET Core را به صورت جداگانه دریافت و نصب کنید. هرچند اگر از این متاپکیجها استفاده نکنید و بستههای مورد نیاز را به صورت مستقیم به برنامهی خود اضافه کنید، این بستهها جزئی از فایلهای publish نهایی بوده و در این حالت برنامه توسط بستهی runtime نیز قابل اجرا است.
در این حالت برنامهی dotnet بجز اجرای برنامهها و ارائهی اطلاعاتی در مورد خود آن، کارهای دیگری را مانند build و یا publish، نمیتواند انجام دهد و برنامه در این حالت باید کاملا از پیش کامپایل شده باشد.
بنابراین دلیل نصب آن میتواند شامل یکی از موارد زیر باشد:
- برای اجرای برنامههای از پیش کامپایل شدهای که به همراه تمام وابستگیهای مورد نیاز هم هستند.
- برای اجرای برنامههای وبی که از ASP.NET Meta packages استفاده نمیکنند
ASP.NET Core Installer
همانطور که در توضیحات بستهی runtime عنوان شد، این بسته، متاپکیجهای ASP.NET Core را به همراه ندارد. اگر به آنها نیاز دارید، باید آنها را به صورت جداگانه توسط ASP.NET Core installer نصب کنید که شامل این موارد است:
- The ASP.NET Runtime Meta Packages - Microsoft.AspNetCore.App - Microsoft.AspNetCore.All
نصب این بسته برای هاست برنامههای ASP.NET Core در ویندوز و بر روی IIS ضروری است و شامل این اجزا میشود:
- 32 bit and 64 .NET Core Runtimes - ASP.NET Runtime Packages (Microsoft.AspNetCode.App/All) - IIS Hosting Components
بنابراین به صورت خلاصه
برای سرورها این موارد را نصب کنید:
- در ویندوز: Windows Server Hosting Bundle
- برای Mac و لینوکس: .NET Core Runtime + ASP.NET Core Runtimes
برای سیستم توسعهی شخصی این موارد را نصب کنید:
- SDK
- اگر از ویندوز استفاده میکنید: Visual Studio هم به همراه SDK نصب میشود.
برای اجرای برنامههای از پیش کامپایل شده که به همراه تمام وابستگیهای مورد نیاز هم هستند:
- تنها Runtime را نصب کنید.
اگر این برنامهی از پیش کامپایل شده از ASP.NET Runtime Meta packages استفاده میکند:
- ASP.NET Runtimes را نیز نصب کنید.
پیاده سازی ویژگی Health Check بدون استفاده از قابلیتهای ASP.NET Core 2.2
اگر بخواهیم در بررسی سلامت برنامه، وضعیت بانک اطلاعاتی آنرا گزارش دهیم، میتوان یک چنین اکشن متدی را طراحی کرد که در آن اتصالی به بانک اطلاعاتی باز شده و اگر در حین فراخوانی مسیر working/، استثنائی رخ داد، با بازگشت status code مساوی 503، عدم سلامت برنامه اعلام شود؛ کاری که سرویسهای ping متداول نمیتوانند آنرا با این دقت انجام دهند:
[Route("working")] public ActionResult Working() { using (var connection = new SqlConnection(_connectionString)) { try { connection.Open(); } catch (SqlException) { return new HttpStatusCodeResult(503, "Generic error"); } } return new EmptyResult(); }
بازنویسی قطعه کد فوق با ویژگی جدید Health Check در ASP.NET Core 2.2
اکنون اگر بخواهیم قطعه کد فوق را با کمک ویژگیهای جدید ASP.NET Core 2.2 بازنویسی کنیم، روش کار به صورت زیر خواهد بود:
namespace MvcHealthCheckTest { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddHealthChecks() .AddCheck("sql", () => { using (var connection = new SqlConnection(Configuration["connectionString"])) { try { connection.Open(); } catch (SqlException) { return HealthCheckResult.Unhealthy(); } } return HealthCheckResult.Healthy(); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseHealthChecks("/working");
- سپس توسط متد app.UseHealthChecks، بدون اینکه نیاز باشد کنترلر و اکشن متد جدیدی را جهت بازگشت وضعیت سلامت برنامه، تعریف کنیم، مسیر working/ قابل دسترسی خواهد شد.
تا اینجا اگر این مسیر را به سرویس بررسی uptime برنامهی خود معرفی کنید، صرفا وضعیت قابل دسترسی بودن مسیر working/ را دریافت خواهید کرد. اگر نیاز به گزارش دقیقتری وجود داشت، میتوان به کمک متد AddCheck، یک منطق سفارشی را نیز به آن افزود؛ همانند بررسی امکان اتصال به بانک اطلاعاتی، به روشی که ملاحظه میکنید. در اینجا اگر منطق مدنظر با موفقیت اجرا شد، HealthCheckResult.Healthy بازگشت داده میشود و یا HealthCheckResult.Unhealthy در صورت عدم موفقیت. هر کدام از این متدها میتوانند توضیحات و یا اطلاعات بیشتری را نیز توسط پارامترهای خود ارائه دهند.
امکان تهیه سرویسهای سفارشی بررسی سلامت برنامه
در مثال قبل، منطق بررسی سلامت برنامه را همانجا داخل متد ConfigureServices، به کمک متد services.AddHealthChecks().AddCheck معرفی کردیم. امکان انتقال این کدها به سرویسهای سفارشی، با پیاده سازی اینترفیس IHealthCheck نیز وجود دارد:
public class SqlServerHealthCheck : IHealthCheck { private readonly IConfiguration _configuration; public SqlServerHealthCheck(IConfiguration configuration) { _configuration = configuration; } public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { using (var connection = new SqlConnection(_configuration["connectionString"])) { try { connection.Open(); } catch (SqlException) { return Task.FromResult(HealthCheckResult.Unhealthy()); } } return Task.FromResult(HealthCheckResult.Healthy()); } }
namespace MvcHealthCheckTest { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddHealthChecks() .AddCheck<SqlServerHealthCheck>("sql");
سفارشی سازی خروجی بررسی سلامت برنامهها
تا اینجا از متدهای کلی Unhealthy و Healthy برای بازگشت وضعیت سلامت برنامه استفاده کردیم؛ خروجیهای بهتری را نیز میتوان ارائه داد:
public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { using (var connection = new SqlConnection(_configuration["connectionString"])) { try { connection.Open(); } catch (SqlException) { return Task.FromResult(new HealthCheckResult( status: context.Registration.FailureStatus, description: "It is dead!")); } } return Task.FromResult(HealthCheckResult.Healthy("Healthy as a horse")); }
روش دیگر سفارشی سازی خروجی آن، استفاده از پارامتر دوم متد app.UseHealthChecks است:
namespace MvcHealthCheckTest { public class Startup { public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseHealthChecks("/working", new HealthCheckOptions { ResponseWriter = async (context, report) => { var result = JsonConvert.SerializeObject(new { status = report.Status.ToString(), errors = report.Entries.Select(e => new { key = e.Key, value = Enum.GetName(typeof(HealthStatus), e.Value.Status) }) }); context.Response.ContentType = MediaTypeNames.Application.Json; await context.Response.WriteAsync(result); } });
معرفی کتابخانهای از IHealthCheckهای سفارشی
از مخزن کد AspNetCore.Diagnostics.HealthChecks میتوانید IHealthCheckهای سفارشی مخصوص SQL Server، MySQL و غیره را نیز دریافت و استفاده کنید.
مسیر راه NET Core 2.1.
[CLI] Build-time performance improvements.
[CLI] Global tools; replaces .NET CLI Tools (DotNetCliToolReference).
[CoreCLR] Minor-version roll-forward.
[CoreCLR] No-copy array slicing with Span<T>.
[CoreFX] HttpClient performance improvements.
[CoreFX] Windows Compatibility Pack.
[ASP.NET] SignalR is available for .NET Core.
[ASP.NET] HTTPS is on by default for ASP.NET.
[EF] Basic lazy loading support.
[EF] Support for Azure Cosmos DB.
Custom error pages in ASP.NET MVC Core
app.Use(async (ctx, next) => { await next(); if(ctx.Response.StatusCode == 404 && !ctx.Response.HasStarted) { //Re-execute the request so the user gets the error page string originalPath = ctx.Request.Path.Value; ctx.Items["originalPath"] = originalPath; ctx.Request.Path = "/error/404"; await next(); } });