background-clip
is one of those properties I've known about for years, but rarely used. Maybe just a couple of times as part of a solution to a Stack Overflow question. Until last year, when I started creating my huge collection of sliders. Some of the designs I chose to reproduce were a bit more complex and I only had one element available per slider, which happened to be an input
element, meaning that I couldn't even use pseudo-elements on it. Even though that does work in certain browsers, the fact that it works is actually a bug and I didn't want to rely on that. All this meant I ended up using backgrounds, borders, and shadows a lot. I also learned a lot from doing that and this article shares some of those lessons.
ساخت بستههای نیوگت مخصوص NET Core.
Visual Studio اگر فایل README.txt را در پوشهی ریشهی یک بستهی نیوگت پیدا کند، پس از نصب بسته، به صورت خودکار آنرا نمایش میدهد. بنابراین با استفاده از این فایل ویژه میتوان نکات جدید مرتبط با بستهی نیوگت، راهنما و یا مثالهایی را به استفاده کننده نمایش داد. اما در پروژههای NET Core.، چگونه میتوان این فایل را در زمان فراخوانی دستور dotnet pack، به بستهی نهایی تولید شده اضافه کرد؟
<Project> … <ItemGroup> <Content Include="README.txt"> <Pack>true</Pack> <PackagePath>README.txt</PackagePath> </Content> </ItemGroup> … </Project>
Include به مسیر فایل الحاق شده اشاره میکند. این مسیر نسبت به ریشهی پروژهی جاری محاسبه میشود.
Pack الحاق و یا عدم الحاق فایل را تنظیم میکند.
PackagePath به مسیر نهایی این فایل در بستهی نیوگت اشاره میکند و نسبت به ریشهی آن درنظر گرفته خواهد شد.
استفاده از NuGet Package Manager برای مدیریت وابستگیها
درباره اهمیت NuGet برای مصرف کنندگان قبلا این مطلب نوشته شده است.
بجای صرف وقت برای اینکه بررسی کنیم آیا این نسخهی جدید کتابخانهی X یا اسکریپت jQuery آمده است یا خیر، میتوان این وظیفه را به NuGet سپرد. علاوه بر این NuGet مزیتهای دیگری هم دارد؛ مثلا تیمهای برنامه نویسی میتوانند کتاب خانههای مشترک خودشان را در مخزنهای سفارشی NuGet قرار دهند و توزیع و Versioning آنرا به NuGet بسپارند.
تکیه بر Abstraction (انتزاع)
Abstraction در طراحی سیستمها منجر به تولید نرم افزار هایی Loosely coupled با قابلیت نگهداری بالا و همچنین فراهم شدن زمینه برای نوشتن Unit Test میشود.
اگر به مطالب قبلی وب سایت برگردیم در مطلب چرا ASP.NET MVC گفته شد که :
2) دستیابی به کنترل بیشتر بر روی اجزای فریم ورک :
در طراحی ASP.NET MVC همهجا interfaceها قابل مشاهد هستند. همین مساله به معنای افزونه پذیری اکثر قطعات تشکیل دهنده ASP.NET MVC است؛ برخلاف ASP.NET web forms. برای مثال تابحال چندین view engine، routing engine و غیره توسط برنامه نویسهای مستقل برای ASP.NET MVC طراحی شدهاند که هیچکدام با ASP.NET web forms میسر نیست. برای مثال از view engine پیش فرض آن خوشتان نمیآید؟ عوضش کنید! سیستم اعتبار سنجی توکار آنرا دوست ندارید؟ آنرا با یک نمونه بهتر تعویض کنید و الی آخر ...
به علاوه طراحی بر اساس interfaceها یک مزیت دیگر را هم به همراه دارد و آن هم ساده سازی mocking (تقلید) آنها است جهت ساده سازی نوشتن آزمونهای واحد.
از کلمهی کلیدی New استفاده نکنید
هر جا ممکن است کار وهله سازی اشیاء را به لایه و حتی Framework دیگری بسپارید. هر زمان اشیاء نرم افزار خودتان را با کلمهی new وهله سازی میکنید اصل Abstraction را فراموش کرده اید. هر زمان اشیاء نرم افزار را مستقیم وهله سازی میکنید در نظر داشته باشید میتوانید آنها را به صورت وابستگی تزریق کنید.
در همین رابطه مطالب زیر را از دست ندهید :
- تزریق وابستگی (dependency injection) به زبان ساده
- تزریق وابستگی (Dependency Injection) و توسعه پذیری
از HttpContext مستقیما استفاده نکنید (از HttpContextBase استفاده کنید)
از .NET 4 به بعد فضای نامی تعریف شده که در بر دارندهی کلاسهای انتزاعی (Abstraction) خیلی از قسمتهای اصلی ASP.NET است. یکی از مواردی که در توسعهی ASP.NET معمولا زیاد استفاده میشود، شیء HttpContext است . استفاده از HttpContextBase را به استفاده از HttpContext ترجیح دهید. اهمیت این موضوع در راستای اهمیت انتزاع (Abstraction) میباشد.
از "رشتههای جادویی" اجتناب کنید
استفاده از رشتههای جادویی در خیلی از جاها کار را ساده میکند؛ بعضی وقتها هم به آنها نیاز است اما مشکلات زیادی دارند :
- رشتهها معنای باطنی ندارند (مثلا : دشوار است که از روی نام یک ID مشخص کنم این ID چطور به ID دیگری مرتبط است و یا اصلا ربط دارد یا خیر)
- با اشتباهات املایی یا عدم رعایت حروف بزرگ و کوچک ایجاد مشکل میکنند.
- به Refactoring واکنش خوبی نشان نمیدهند. (برای درک بهتر این مطلب را بخوانید.)
<p> <label for="FirstName">First Name:</label> <span id="FirstName">@ViewData["FirstName"]</span> </p>
<p> <label for="FirstName">First Name:</label> <span id="FirstName">@Model.FirstName</span> </p>
در رابطه با Magic strings این مطلب را مطالعه بفرمایید.
از نوشتن HTML در کدهای "Backend" خودداری کنید
با توجه به اصل جداسازی وابستگیها (Separation of Concerns) وظیفهی کنترلرها و دیگر کدهای backend رندر کردن HTML نیست. (ساده سازی کنترلر ها) البته در نظر داشته باشید که قطعا تولید HTML در متدهای کمکی کلاس هایی که "تنها" وظیفهی آنها کمک به Viewها جهت تولید کد هست ایرادی ندارد. این کلاسها بخشی از View در نظر گرفته میشوند نه کدهای "backend".
در Viewها "Business logic" انجام ندهید
معکوس بند قبلی هم کاملا صدق میکند ، منظور این است که Viewها تا جایی که ممکن است باید حاوی کمترین Business logic ممکن باشند. در واقع تمرکز Viewها باید استفاده و نحوهی نمایش داده ای که برای آنها فراهم شده باشد نه انجام عملیات روی آن.
استفاده از Presentation Model را به استفاده مستقیم از Business Objectها ترجیح دهید
در مطالب مختلف وب سایت اشاره به اهمین ViewModelها شده است. برای اطلاعات بیشتر بند ج آموزش 11 از سری آموزشهای ASP.NET MVC را مطالعه بفرمایید.
Ifهای شرطی را در Viewها را در متدهای کمکی کپسوله کنید
استفاده از شرطها در View کار توسعه دهنده را برای یک سری اعمال ساده میکند اما میتواند باعث کمی کثیف کاری هم شود. مثلا:
@if(Model.IsAnonymousUser) { <img src="@Url.Content("~/content/images/anonymous.jpg")" /> } else if(Model.IsAdministrator) { <img src="@Url.Content("~/content/images/administrator.jpg")" /> } else if(Model.Membership == Membership.Standard) { <img src="@Url.Content("~/content/images/member.jpg")" /> } else if(Model.Membership == Membership.Preferred) { <img src="@Url.Content("~/content/images/preferred_member.jpg")" /> }
public static string UserAvatar(this HtmlHelper<User> helper) { var user = helper.ViewData.Model; string avatarFilename = "anonymous.jpg"; if (user.IsAnonymousUser) { avatarFilename = "anonymous.jpg"; } else if (user.IsAdministrator) { avatarFilename = "administrator.jpg"; } else if (user.Membership == Membership.Standard) { avatarFilename = "member.jpg"; } else if (user.Membership == Membership.Preferred) { avatarFilename = "preferred_member.jpg"; } var urlHelper = new UrlHelper(helper.ViewContext.RequestContext); var contentPath = string.Format("~/content/images/{0}", avatarFilename) string imageUrl = urlHelper.Content(contentPath); return string.Format("<img src='{0}' />", imageUrl); }
@Html.UserAvatar()
منتظر قسمت بعدی باشید.
هدایت سراسری و خودکار کاربران اعتبارسنجی نشده به صفحهی لاگین
در برنامهی این سری، اگر کاربری که به سیستم وارد نشدهاست، بر روی دکمهی Book یک اتاق کلیک کند، فقط پیام «Not Authorized» را مشاهده خواهد کرد که تجربهی کاربری مطلوبی بهشمار نمیرود. بهتر است در یک چنین حالتی، کاربر را به صورت خودکار به صفحهی لاگین هدایت کرد و پس از لاگین موفق، مجددا او را به همین آدرس درخواستی پیش از نمایش صفحهی لاگین، هدایت کرد. برای مدیریت این مساله کامپوننت جدید RedirectToLogin را طراحی میکنیم که جایگزین پیام «Not Authorized» در کامپوننت ریشهای BlazorWasm.Client\App.razor خواهد شد. بنابراین ابتدا فایل جدید BlazorWasm.Client\Pages\Authentication\RedirectToLogin.razor را ایجاد میکنیم. چون این کامپوننت بدون مسیریابی خواهد بود و قرار است مستقیما داخل کامپوننت دیگری درج شود، نیاز است فضای نام آنرا نیز به فایل BlazorWasm.Client\_Imports.razor اضافه کرد:
@using BlazorWasm.Client.Pages.Authentication
@using System.Security.Claims @inject NavigationManager NavigationManager if(AuthState is not null) { <div class="alert alert-danger"> <p>You [@AuthState.User.Identity.Name] do not have access to the requested page</p> <div> Your roles: <ul> @foreach (var claim in AuthState.User.Claims.Where(c => c.Type == ClaimTypes.Role)) { <li>@claim.Value</li> } </ul> </div> </div> } @code { [CascadingParameter] private Task<AuthenticationState> AuthenticationState {set; get;} AuthenticationState AuthState; protected override async Task OnInitializedAsync() { AuthState = await AuthenticationState; if (!IsAuthenticated(AuthState)) { var returnUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri); if (string.IsNullOrEmpty(returnUrl)) { NavigationManager.NavigateTo("login"); } else { NavigationManager.NavigateTo($"login?returnUrl={Uri.EscapeDataString(returnUrl)}"); } } } private bool IsAuthenticated(AuthenticationState authState) => authState?.User?.Identity is not null && authState.User.Identity.IsAuthenticated; }
در اینجا روش کار کردن با AuthenticationState را از طریق کدنویسی ملاحظه میکنید. در زمان بارگذاری اولیهی این کامپوننت، بررسی میشود که آیا کاربر جاری، به سیستم وارد شدهاست یا خیر؟ اگر خیر، او را به سمت صفحهی لاگین هدایت میکنیم. اما اگر کاربر پیشتر به سیستم وارد شده باشد، متن شما دسترسی ندارید، به همراه لیست نقشهای او در صفحه ظاهر میشوند که برای دیباگ برنامه مفید است و دیگر به سمت صفحهی لاگین هدایت نمیشود.
در ادامه برای استفاده از این کامپوننت، به کامپوننت ریشهای BlazorWasm.Client\App.razor مراجعه کرده و قسمت NotAuthorized آنرا به صورت زیر، با معرفی کامپوننت RedirectToLogin، جایگزین میکنیم:
<NotAuthorized> <RedirectToLogin></RedirectToLogin> </NotAuthorized>
چگونه دسترسی نقش ثابت Admin را به تمام صفحات محافظت شده برقرار کنیم؟
اگر خاطرتان باشد در زمان ثبت کاربر ادمین Identity، تنها نقشی را که برای او ثبت کردیم، Admin بود که در تصویر فوق هم مشخص است؛ اما ویژگی Authorize استفاده شده جهت محافظت از کامپوننت (attribute [Authorize(Roles = ConstantRoles.Customer)]@)، تنها نیاز به نقش Customer را دارد. به همین جهت است که کاربر وارد شدهی به سیستم، هرچند از دیدگاه ما ادمین است، اما به این صفحه دسترسی ندارد. بنابراین اکنون این سؤال مطرح است که چگونه میتوان به صورت خودکار دسترسی نقش Admin را به تمام صفحات محافظت شدهی با نقشهای مختلف، برقرار کرد؟
برای رفع این مشکل همانطور که پیشتر نیز ذکر شد، نیاز است تمام نقشهای مدنظر را با یک کاما از هم جدا کرد و به خاصیت Roles ویژگی Authorize انتساب داد؛ و یا میتوان این عملیات را به صورت زیر نیز خلاصه کرد:
using System; using BlazorServer.Common; using Microsoft.AspNetCore.Authorization; namespace BlazorWasm.Client.Utils { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class RolesAttribute : AuthorizeAttribute { public RolesAttribute(params string[] roles) { Roles = $"{ConstantRoles.Admin},{string.Join(",", roles)}"; } } }
پس از این تعریف میتوان در کامپوننتها، ویژگی Authorize نقش دار را با ویژگی جدید Roles، جایگزین کرد که همواره دسترسی کاربر Admin را نیز برقرار میکند:
@attribute [Roles(ConstantRoles.Customer, ConstantRoles.Employee)]
مدیریت سراسری خطاهای حاصل از درخواستهای HttpClient
تا اینجا نتایج حاصل از شکست اعتبارسنجی سمت کلاینت را به صورت سراسری مدیریت کردیم. اما برنامههای سمت کلاینت، به کمک HttpClient خود نیز میتوانند درخواستهایی را به سمت سرور ارسال کرده و در پاسخ، برای مثال not authorized و یا forbidden را دریافت کنند و یا حتی internal server error ای را در صورت بروز استثنایی در سمت سرور.
فرض کنید Web API Endpoint جدید زیر را تعریف کردهایم که نقش ادیتور را میپذیرد. این نقش، جزو نقشهای تعریف شدهی در برنامه و سیستم Identity ما نیست. بنابراین هر درخواستی که به سمت آن ارسال شود، برگشت خواهد خورد و پردازش نمیشود:
namespace BlazorWasm.WebApi.Controllers { [Route("api/[controller]")] [Authorize(Roles = "Editor")] public class MyProtectedEditorsApiController : Controller { [HttpGet] public IActionResult Get() { return Ok(new ProtectedEditorsApiDTO { Id = 1, Title = "Hello from My Protected Editors Controller!", Username = this.User.Identity.Name }); } } }
namespace BlazorWasm.Client.Services { public class ClientHttpInterceptorService : DelegatingHandler { private readonly NavigationManager _navigationManager; private readonly ILocalStorageService _localStorage; private readonly IJSRuntime _jsRuntime; public ClientHttpInterceptorService( NavigationManager navigationManager, ILocalStorageService localStorage, IJSRuntime JsRuntime) { _navigationManager = navigationManager ?? throw new ArgumentNullException(nameof(navigationManager)); _localStorage = localStorage ?? throw new ArgumentNullException(nameof(localStorage)); _jsRuntime = JsRuntime ?? throw new ArgumentNullException(nameof(JsRuntime)); } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // How to add a JWT to all of the requests var token = await _localStorage.GetItemAsync<string>(ConstantKeys.LocalToken); if (token is not null) { request.Headers.Authorization = new AuthenticationHeaderValue("bearer", token); } var response = await base.SendAsync(request, cancellationToken); if (!response.IsSuccessStatusCode) { await _jsRuntime.ToastrError($"Failed to call `{request.RequestUri}`. StatusCode: {response.StatusCode}."); switch (response.StatusCode) { case HttpStatusCode.NotFound: _navigationManager.NavigateTo("/404"); break; case HttpStatusCode.Forbidden: // 403 case HttpStatusCode.Unauthorized: // 401 _navigationManager.NavigateTo("/unauthorized"); break; default: _navigationManager.NavigateTo("/500"); break; } } return response; } } }
با ارثبری از کلاس پایهی DelegatingHandler میتوان متد SendAsync تمام درخواستهای ارسالی توسط برنامه را بازنویسی کرد و تحت نظر قرار داد. برای مثال در اینجا، پیش از فراخوانی await base.SendAsync کلاس پایه (یا همان درخواست اصلی که در قسمتی از برنامه صادر شدهاست)، یک توکن را به هدرهای درخواست، اضافه کردهایم و یا پس از این فراخوانی (که معادل فراخوانی اصل کد در حال اجرای برنامه است)، با بررسی StatusCode بازگشتی از سمت سرور، کاربر را به یکی از صفحات یافت نشد، خطایی رخ دادهاست و یا دسترسی ندارید، هدایت کردهایم. برای نمونه کامپوننت Unauthorized.razor را با محتوای زیر تعریف کردهایم:
@page "/unauthorized" <div class="alert alert-danger mt-3"> <p>You don't have access to the requested resource.</p> </div>
پس از تدارک این Interceptor سراسری، نوبت به معرفی آن به برنامهاست که ... در ابتدا نیاز به نصب بستهی نیوگت زیر را دارد:
dotnet add package Microsoft.Extensions.Http
namespace BlazorWasm.Client { public class Program { public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); //... // builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); /*builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.Configuration.GetValue<string>("BaseAPIUrl")) });*/ // dotnet add package Microsoft.Extensions.Http builder.Services.AddHttpClient( name: "ServerAPI", configureClient: client => { client.BaseAddress = new Uri(builder.Configuration.GetValue<string>("BaseAPIUrl")); client.DefaultRequestHeaders.Add("User-Agent", "BlazorWasm.Client 1.0"); } ) .AddHttpMessageHandler<ClientHttpInterceptorService>(); builder.Services.AddScoped<ClientHttpInterceptorService>(); builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("ServerAPI")); //... } } }
کدهای کامل این مطلب را از اینجا میتوانید دریافت کنید: Blazor-5x-Part-33.zip
In this video, I show ten extremely useful Visual Studio features: - Enhanced Clipboard - Run To Cursor Debugging - Tracking Active Solution Explorer Item - Fast File Navigation - Tabs - Previewing and Pinning - Code Cleanup Configuration - Vertical Selection - Better Git Pull - Improved Performance On Load - Special Pasting
EF Code First #10
An unhandled exception of type 'System.NotSupportedException' occurred in EntityFramework.dll Additional information: Unable to determine the DbProviderFactory type for connection of type 'System.Data.SqlClient.SqlConnection'. Make sure that the ADO.NET provider is installed or registered in the application config.
Bridge Network Driver
The bridge
networking driver is the first driver on our list. It’s simple to understand, simple to use, and simple to troubleshoot, which makes it a good networking choice for developers and those new to Docker. The bridge
driver creates a private network internal to the host so containers on this network can communicate. External access is granted by exposing ports to containers. Docker secures the network by managing rules that block connectivity between different Docker networks.
Overlay Network Driver
The built-in Docker overlay
network driver radically simplifies many of the complexities in multi-host networking. It is a swarm scope driver, which means that it operates across an entire Swarm or UCP cluster rather than individual hosts. With the overlay
driver, multi-host networks are first-class citizens inside Docker without external provisioning or components. IPAM, service discovery, multi-host connectivity, encryption, and load balancing are built right in. For control, the overlay
driver uses the encrypted Swarm control plane to manage large scale clusters at low convergence times.
MACVLAN Driver
The macvlan
driver is the newest built-in network driver and offers several unique characteristics. It’s a very lightweight driver, because rather than using any Linux bridging or port mapping, it connects container interfaces directly to host interfaces. Containers are addressed with routable IP addresses that are on the subnet of the external network.
As a result of routable IP addresses, containers communicate directly with resources that exist outside a Swarm cluster without the use of NAT and port mapping. This can aid in network visibility and troubleshooting. Additionally, the direct traffic path between containers and the host interface helps reduce latency. macvlan
is a local scope network driver which is configured per-host. As a result, there are stricter dependencies between MACVLAN and external networks, which is both a constraint and an advantage that is different from overlay
or bridge
.
ASP.NET Core
- قسمت اول: Net Core. چیست؟
- قسمت دوم: بررسی ساختار جدید Solution
- قسمت سوم: Middleware چیست؟
- قسمت چهارم: فعالسازی پردازش فایلهای استاتیک
- قسمت پنجم: فعالسازی صفحات مخصوص توسعه دهنده ها
- قسمت ششم: سرویسها و تزریق وابستگی ها
- قسمت هفتم: کار با فایلهای Config
- قسمت هشتم: فعالسازی ASP.NET MVC
- قسمت نهم: بررسی تغییرات مسیریابی
- قسمت دهم: بررسی تغییرات Viewها
- قسمت یازدهم: بررسی بهبودهای Razor
- قسمت دوازدهم: معرفی Tag Helpers
- قسمت سیزدهم: معرفی View Components
- قسمت چهاردهم: فعال سازی اعتبارسنجی ورودیهای کاربران
- قسمت پانزدهم: بررسی تغییرات Caching
- قسمت شانزدهم:کار با Sessions
- قسمت هفدهم: بررسی فریم ورک Logging
- قسمت هجدهم: کار با ASP.NET Web API
- قسمت نوزدهم: بومی سازی
- قسمت بیستم: بررسی تغییرات فیلترها
- قسمت بیست و یکم: بررسی تغییرات Bundling و Minification
- قسمت بیست و دوم: توزیع برنامه توسط IIS
- پیاده سازی Unobtrusive Ajax در ASP.NET Core 1.0
- امکان استفادهی مستقیم از کتابخانههای Full .NET Framework در NET Core 2.0.
- Tag Helper Components در ASP.NET Core 2.0
- کار با Razor در ASP.NET Core 2.0
- فعالسازی Windows Authentication در برنامههای ASP.NET Core 2.0
ASP.NET Core Identity
- سفارشی سازی
- امکان ساخت قالب برای پروژههای NET Core.
- تبدیل قالبهای سفارشی پروژههای NET Core. به بستههای NuGet
- افزودن و اعتبارسنجی خودکار Anti-Forgery Tokens در برنامههای Angular مبتنی بر ASP.NET Core
- تولید هدرهای Content Security Policy توسط ASP.NET Core برای برنامههای Angular
- غیرمعتبر شدن کوکیهای برنامههای ASP.NET Core هاست شدهی در IIS پس از ریاستارت آن
- اعتبارسنجی مبتنی بر JWT در ASP.NET Core 2.0 بدون استفاده از سیستم Identity
- اعتبارسنجی مبتنی بر کوکیها در ASP.NET Core 2.0 بدون استفاده از سیستم Identity
- فعالسازی HSTS در ASP.NET Core
- مراحل تنظیم Let's Encrypt در IIS
- IdentityServer 4x
- قسمت اول - نیاز به تامین کنندهی هویت مرکزی
- قسمت دوم - ایجاد ساختار اولیهی مثال این سری
- قسمت سوم - بررسی مفاهیم OpenID Connect
- قسمت چهارم - نصب و راه اندازی IdentityServer
- قسمت پنجم - پیاده سازی ورود و خروج از سیستم
- قسمت ششم - کار با User Claims
- قسمت هفتم- امن سازی Web API
- قسمت هشتم- تعریف سطوح دسترسی پیچیده
- قسمت نهم- مدیریت طول عمر توکنها
- قسمت دهم- ذخیره سازی اطلاعات کاربران IDP در بانک اطلاعاتی
- قسمت یازدهم- استفاده از تامین کنندههای هویت خارجی
- قسمت دوازدهم- یکپارچه سازی با اکانت گوگل
- قسمت سیزدهم- فعالسازی اعتبارسنجی دو مرحلهای
- قسمت چهاردهم- آماده شدن برای انتشار برنامه
- قسمت اول - نیاز به تامین کنندهی هویت مرکزی
کار با Areas در ASP.NET Core
کار با کوکیها در ASP.NET Core
بررسی روش آپلود فایلها در ASP.NET Core
ارسال ایمیل در ASP.NET Core
نوشتن Middleware سفارشی در ASP.NET Core
نوشتن TagHelperهای سفارشی برای ASP.NET Core
بررسی تغییرات Reflection در NET Core.
استفادهی گسترده از DateTimeOffset در NET Core.
بررسی روش دسترسی به HttpContext در ASP.NET Core
توزیع پروژههای ASP.NET Core 1.1 بدون ارائه فایلهای View آن
تغییرات رمزنگاری اطلاعات در NET Core.
ساخت بستههای نیوگت مخصوص NET Core.
تهیه قالب برای ارسال ایمیلها در ASP.NET Core توسط Razor Viewها
روش یافتن لیست تمام کنترلرها و اکشن متدهای یک برنامهی ASP.NET Core
بررسی روش آپلود فایلها از طریق یک برنامهی Angular به یک برنامهی ASP.NET Core
سفارشی سازی صفحهی اول برنامههای Angular CLI توسط ASP.NET Core
تغییرات Encoding در NET Core.
پیاده سازی برنامههای چند مستاجری در ASP.NET Core
مقدمهای بر تزریق وابستگیها درASP.NET Core
نمایش خطاهای اعتبارسنجی سمت سرور ASP.NET Core در برنامههای Angular
احراز هویت و اعتبارسنجی کاربران در برنامههای Angular - قسمت اول - معرفی و ایجاد ساختار برنامه
روش استفادهی صحیح از HttpClient در برنامههای دات نت
اجرای سرویسهای NodeJS در ASP.NET Core
بررسی خطاهای ممکن در حین راه اندازی اولیه برنامههای ASP.NET Core در IIS
تست کردن متدهای یک Controller به کمک PowerShell
کار با Visual Studio در ASP.NET Core