A few years ago, we took over maintenance and guidance for the ASP.NET AJAX Control Toolkit project. Please refer to this blog post for more information on the project and why we stepped in to assist.
As part of our ongoing commitment to the project, we’ve released an update (ASP.NET AJAX Control Toolkit v19.1.0) to address the following issues.
Improvements
- Visual Studio 2019 Support
- Security hardening: HTML-encode file names in AjaxFileUpload (#483)
مرحلهی اول: نصب SDK مربوطه
در این تاریخ، این SDK در مرحلهی پیشنمایش است و نگارش نهایی آن قرار است صرفا با VS 2019 سازگار و هماهنگ باشد (و با VS 2017 کار نمیکند)؛ اما هم اکنون در VSCode قابل استفادهاست. برای این منظور SDK آنرا از آدرس https://dotnet.microsoft.com/download/dotnet-core/3.0 دریافت و نصب کنید. پس از نصب، یک چنین خروجی را در خط فرمان مشاهده خواهید کرد:
> dotnet --version 3.0.100-preview-010184
مشکل: پس از نصب نگارش 3، ممکن است برنامههایی که از SDK نگارش 2 استفاده میکنند، به مشکل بر بخورند.
راه حل: برنامههای مبتنی بر NET Core.، شماره نگارش SDK خود را از فایل ویژهای به نام global.json دریافت میکنند. اگر این فایل در ریشهی پروژهی شما وجود نداشته باشد، یعنی همواره از آخرین شمارهی SDK نصب شده استفاده شود. بنابراین ابتدا لیست SDKهای نصب شده را با دستور زیر پیدا کنید:
> dotnet --list-sdks
> dotnet new globaljson --sdk-version 2.2.100 > type global.json
مرحلهی دوم: نصب افزونهی پیشنمایش VSCode مخصوص C# 8.0
در این تاریخ هنوز این افزونه در نگارش بتای آن قرار دارد. بنابراین در لیست دریافتهای خودکار VSCode قرار نمیگیرد و باید دستی نصب شود. برای این منظور به آدرس https://github.com/OmniSharp/omnisharp-vscode/releases مراجعه کرده و آخرین نگارش بتای آنرا دریافت کنید.
در VSCode، قسمتیکه افزونهها را نمایش میدهد، یک دکمهی ... مانند وجود دارد. بر روی آن که کلیک کنید. در منوی باز شده، گزینهی install from vsix نیز موجود است که دقیقا برای نصب دستی یک چنین افزونههایی پیشبینی شدهاست. پس از نصب فایل vsix دریافت شدهی از GitHub، شماره نگارش 1.18.0-beta7 در قسمت افزونههای VSCode قابل مشاهده خواهد بود.
مرحلهی آخر: ایجاد یک پروژهی جدید مخصوص NET Core 3x. با پشتیبانی از C# 8.0
اکنون یک پوشهی جدید را ایجاد کرده و در خط فرمان دستور dotnet new console را صادر کنید. سپس فایل csproj آنرا به صورت زیر تغییر دهید تا از NET Core 3x. و C# 8.0 و قابلیت جدید Nullable Reference Types آن پشتیبانی کند:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <LangVersion>8.0</LangVersion> <NullableContextOptions>enable</NullableContextOptions> </PropertyGroup> </Project>
معرفی JSON Web Token
- برای سفارشی سازی ASP.NET Identity از مطلب «اعمال تزریق وابستگیها به مثال رسمی ASP.NET Identity» ایده بگیرید.
سفارشی سازی نرمال سازها
اگر به طراحی جداول ASP.NET Core Identity دقت کنید، تعدادی فیلد اضافی حاوی کلمهی Normalized را هم مشاهده خواهید کرد. برای مثال:
در جدول کاربران، فیلدهای Email و UserName به همراه دو فیلد اضافهی NormalizedEmail و NormalizedUserName وجود دارند.
مقدار دهی و مدیریت این فیلدهای ویژه به صورت خودکار توسط کلاسی به نام UpperInvariantLookupNormalizer صورت میگیرد:
public class UpperInvariantLookupNormalizer : ILookupNormalizer
همانطور که در مطلب «نرمال سازی اطلاعات کاربران در حین ثبت نام» نیز عنوان شد، برای مثال ایمیلهای جیمیل را میتوان با چندین حالت مختلف ثبت کرد و یک کاربر به این صورت میتواند شرط یکتا بودن آدرس ایمیلهای تنظیم شدهی در کلاس IdentityServicesRegistry را دور بزند:
identityOptionsUser.RequireUniqueEmail = true;
چون تنها یک اینترفیس ILookupNormalizer وجود دارد، باید بر اساس محتوای کلیدی که به آن ارسال میشود:
public override string Normalize(string key)
پس از تدارک کلاس CustomNormalizer، تنها کاری را که باید در جهت معرفی و جایگرینی آن انجام داد، تغییر ذیل در کلاس IdentityServicesRegistry است:
services.AddScoped<ILookupNormalizer, CustomNormalizer>(); services.AddScoped<UpperInvariantLookupNormalizer, CustomNormalizer>();
بنابراین دیگر نیازی نیست تا در حین ثبتنام نسبت به تمیزسازی ایمیلها و یا نامهای کاربری اقدام کنیم. سرویس ILookupNormalizer در پشت صحنه به صورت خودکار در تمام مراحل ثبت نام و به روز رسانیها توسط ASP.NET Core Identity استفاده میشود.
سفارشی سازی UserValidator
ASP.NET Core Identity به همراه یک سرویس توکار اعتبارسنج کاربران است که با پیاده سازی اینترفیس IUserValidator ارائه شدهاست:
public class UserValidator<TUser> : IUserValidator<TUser> where TUser : class
بنابراین اگر قصد تهیهی یک IUserValidator جدید را داشته باشیم، از تمام تنظیمات و بررسیهای پیش فرض سرویس توکار UserValidator فوق محروم میشویم. به همین جهت برای سفارشی سازی این سرویس، از خود کلاس UserValidator ارث بری کرده و سپس base.ValidateAsync آنرا فراخوانی میکنیم. با اینکار سبب خواهیم شد تا تمام اعتبارسنجیهای پیشفرض ASP.NET Core Identity اعمال شده و پس از آن منطقهای سفارشی اعتبارسنجی خود را که در کلاس CustomUserValidator قابل مشاهده هستند، اضافه میکنیم.
public override async Task<IdentityResult> ValidateAsync(UserManager<User> manager, User user) { // First use the built-in validator var result = await base.ValidateAsync(manager, user).ConfigureAwait(false); var errors = result.Succeeded ? new List<IdentityError>() : result.Errors.ToList(); // Extending the built-in validator validateEmail(user, errors); validateUserName(user, errors); return !errors.Any() ? IdentityResult.Success : IdentityResult.Failed(errors.ToArray()); }
پس از تدارک کلاس CustomUserValidator، تنها کاری را که باید در جهت معرفی و جایگرینی آن انجام داد، تغییر ذیل در کلاس IdentityServicesRegistry است:
services.AddScoped<IUserValidator<User>, CustomUserValidator>(); services.AddScoped<UserValidator<User>, CustomUserValidator>();
سفارشی سازی PasswordValidator
مراحل سفارشی سازی اعتبارسنج کلمات عبور نیز همانند تهیهی CustomUserValidator فوق است.
ASP.NET Core Identity به همراه یک سرویس توکار اعتبارسنج کلمات عبور کاربران است که با پیاده سازی اینترفیس IPasswordValidator ارائه شدهاست:
public class PasswordValidator<TUser> : IPasswordValidator<TUser> where TUser : class
private static void setPasswordOptions(PasswordOptions identityOptionsPassword, SiteSettings siteSettings) { identityOptionsPassword.RequireDigit = siteSettings.PasswordOptions.RequireDigit; identityOptionsPassword.RequireLowercase = siteSettings.PasswordOptions.RequireLowercase; identityOptionsPassword.RequireNonAlphanumeric = siteSettings.PasswordOptions.RequireNonAlphanumeric; identityOptionsPassword.RequireUppercase = siteSettings.PasswordOptions.RequireUppercase; identityOptionsPassword.RequiredLength = siteSettings.PasswordOptions.RequiredLength; }
"PasswordOptions": { "RequireDigit": false, "RequiredLength": 6, "RequireLowercase": false, "RequireNonAlphanumeric": false, "RequireUppercase": false },
بنابراین در اینجا نیز ارائهی یک پیاده سازی خام از IPasswordValidator سبب خواهد شد تا تمام اعتبارسنجیهای توکار کلاس PasswordValidator اصلی را از دست بدهیم. به همین جهت کار را با ارث بری از همین کلاس توکار شروع کرده و ابتدا متد base.ValidateAsync آنرا فراخوانی میکنیم تا مطمئن شویم، مدخل PasswordOptions تنظیمات یاد شده، حتما پردازش خواهند شد. سپس منطق سفارشی خود را اعمال میکنیم.
برای مثال در کلاس CustomPasswordValidator تهیه شده، به مدخل PasswordsBanList فایل appsettings.json مراجعه شده و کاربران را از انتخاب کلمات عبوری به شدت ساده، منع میکند.
پس از تدارک کلاس CustomPasswordValidator، تنها کاری را که باید در جهت معرفی و جایگرینی آن انجام داد، تغییر ذیل در کلاس IdentityServicesRegistry است:
services.AddScoped<IPasswordValidator<User>, CustomPasswordValidator>(); services.AddScoped<PasswordValidator<User>, CustomPasswordValidator>();
پردازش نتایج اعتبارسنجها
این اعتبارسنجها در خروجیهای IdentityResult تمام متدهای ASP.NET Core Identity ظاهر میشوند. بنابراین فراخوانی سادهی UpdateUserAsync اشتباه است و حتما باید خروجی آنرا جهت پردازش IdentityResult آن بررسی کرد. به همین جهت تعدادی متد الحاقی به کلاس IdentityExtensions اضافه شدهاند تا کارکردن با IdentityResult را سادهتر کنند.
public static void AddErrorsFromResult(this ModelStateDictionary modelStat, IdentityResult result)
public static string DumpErrors(this IdentityResult result, bool useHtmlNewLine = false)
استفادهی از این متدهای الحاقی را در کنترلرهای برنامه میتوانید مشاهده کنید.
استفادهی از اعتبارسنجها جهت انجام Remote validation
اگر به RegisterController دقت کنید، اکشن متدهای ValidateUsername و ValidatePassword قابل مشاهده هستند:
[AjaxOnly, HttpPost, ValidateAntiForgeryToken] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] public async Task<IActionResult> ValidateUsername(string username, string email)
[AjaxOnly, HttpPost, ValidateAntiForgeryToken] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] public async Task<IActionResult> ValidatePassword(string password, string username)
IPasswordValidator<User> passwordValidator, IUserValidator<User> userValidator,
به این ترتیب کاربران در حین ثبت نام، راهنمای بهتری را جهت انتخاب کلمات عبور و نام کاربری مشاهده خواهند کرد و این بررسیها نیز Ajax ایی هستند و پیش از ارسال فرم نهایی به سرور اتفاق میافتند.
برای فعالسازی Remote validation، علاوه بر ثبت اسکریپتهای Ajax ایی، خواص کلاس RegisterViewModel نیز از ویژگی Remote استفاده میکنند:
[Required(ErrorMessage = "(*)")] [Display(Name = "نام کاربری")] [Remote("ValidateUsername", "Register", AdditionalFields = nameof(Email) + "," + ViewModelConstants.AntiForgeryToken, HttpMethod = "POST")] [RegularExpression("^[a-zA-Z_]*$", ErrorMessage = "لطفا تنها از حروف انگلیسی استفاده نمائید")] public string Username { get; set; }
یک نکته: برای اینکه Remote Validation را به همراه ValidateAntiForgeryToken استفاده کنیم، تنها کافی است نام فیلد مخفی آنرا به لیست AdditionalFields به نحوی که مشاهده میکنید، اضافه کنیم.
کدهای کامل این سری را در مخزن کد DNT Identity میتوانید ملاحظه کنید.
- Edit Continue Crashes IDE
- Link.exe exited with code - 1073741819 when generating map files.
- ClickOnce installer prerequisite vcredist 14 (x64) is invalid after download
- Every time I hit a breakpoint and apply changes with edit & continue Visual Studio crashes to desktop
- Fixed crash when editing code while debugging ASP.NET applications.
ASP.NET Core 3.0 Preview 9 منتشر شد
To get started with ASP.NET Core in .NET Core 3.0 Preview 9 install the .NET Core 3.0 Preview 9 SDK.
If you’re on Windows using Visual Studio, install the latest preview of Visual Studio 2019.
.NET Core 3.0 Preview 9 requires Visual Studio 2019 16.3 Preview 3 or later.