مسیرراه‌ها
Blazor 5x

مبانی Blazor 

 احراز هویت و اعتبارسنجی کاربران Blazor Server

تهیه API مخصوص Blazor WASM
Blazor WASM 

احراز هویت و اعتبارسنجی کاربران Blazor WASM

توزیع برنامه 

مدیریت استثناءها

بررسی تغییرات Blazor 8x  

مطالب تکمیلی
اشتراک‌ها
بررسی زبان Go برای توسعه دهندگان #C

A Tour of Go (golang) for the C# Developer

Learning other programming languages enhances our work in our primary language. From the perspective of a C# developer, the Go language (golang) has many interesting ideas. Go is opinionated on some things (such as where curly braces go and what items are capitalized). Declaring an unused variable causes a compile failure; the use of "blank identifiers" (or "discards" in C#) are common. Concurrency is baked right in to the language through goroutines and channels. Programming by exception is discouraged; it's actually called a "panic" in Go. Instead, errors are treated as states to be handled like any other data state. We'll explore these features (and others) by building an application that uses concurrent operations to get data from a service. These ideas make us think about the way we program and how we can improve our day-to-day work (in C# or elsewhere).

0:00 Welcome to Go
2:40 Step 1: Basics
12:20 Step 2: Calling a web service
23:35 Step 3: Parsing JSON
36:26 Step 4: "for" loops
41:00 Step 5: Interfaces and methods
50:05 Step 6: Time and Args
55:10 Step 7: Concurrency
1:07:10 Step 8: Errors
1:14:40 Step 9: Concurrency and errors
1:24:35 Where to go next 

بررسی زبان Go برای توسعه دهندگان #C
اشتراک‌ها
نکاتی در رابطه با ویژگی‌های جدید C# 7.0

C# 7 is a major update with a lot of interesting new capabilities. And while there are plenty of articles on what you can do with it, there aren't quite as many on what you should do with it. Using the principles found in the .NET Framework Design Guidelines, we're going to take a first pass at laying down strategies for getting the most from these new features. 

نکاتی در رابطه با ویژگی‌های جدید C# 7.0
اشتراک‌ها
7 نکته برای حفظ سلامتی برنامه نویس‌ها
You don't know what you have until you lose it. We all know what it means, but we often forget that it also applies to our health. In no way is this article intended to lecture you or make you feel guilty about your lifestyle. With this article, I simply want to share a few tips that can help you stay healthy as a programmer.
7 نکته برای حفظ سلامتی برنامه نویس‌ها
مطالب
کوئری نویسی در EF Core - قسمت چهارم - اعمال تغییرات در داده‌ها
نوع دیگری از کوئری‌های پرکاربرد، کوئری‌های مرتبط با ثبت، حذف و ویرایش اطلاعات هستند که در این قسمت آن‌ها را بررسی می‌کنیم. البته این مثال‌ها از یکسری مثال کوئری‌های مرتبط با PostgreSQL، به EF-Core تبدیل و ترجمه شده‌اند. به همین جهت تطابق یک به یکی در اینجا وجود نداشته و روش شیءگرایی که ORMها برای کار با داده‌ها بکار می‌گیرند، الزاما کوئری‌های یکسانی را تولید نمی‌کنند؛ اما نتیجه‌ی نهایی آن‌ها یکی است.


مثال 1: افزودن ردیفی به یک جدول بانک اطلاعاتی

امکان و ویژگی جدیدی به نام SPA قرار است به مجموعه اضافه شود. اطلاعات آن که شامل موارد ذیل است، نیاز است به جدول facilities اضافه شود:
facid: 9, Name: 'Spa', membercost: 20, guestcost: 30, initialoutlay: 100000, monthlymaintenance: 800.
اگر قرار باشد چنین کاری را توسط دستورات SQL انجام دهیم، عموما به یکی از دو روش زیر عمل می‌شود:
insert into facilities
    (facid, name, membercost, guestcost, initialoutlay, monthlymaintenance)
    values (9, 'Spa', 20, 30, 100000, 800);
-- OR
insert into facilities values (9, 'Spa', 20, 30, 100000, 800);
که معادل آن در EF-Core به صورت زیر است:
context.Facilities.Add(new Facility
                {
                    Name = "Spa",
                    MemberCost = 20,
                    GuestCost = 30,
                    InitialOutlay = 100000,
                    MonthlyMaintenance = 800
                });
context.SaveChanges();
ابتدا وهله‌ای از موجودیت Facility به DbSet مرتبط با آن اضافه می‌شود و در آخر SaveChanges فراخوانی خواهد شد تا کوئری متناظر با آن ساخته شده و به بانک اطلاعاتی اعمال شود.


مثال 2: افزودن چندین ردیف از اطلاعات به یک جدول بانک اطلاعاتی

همان مثال قبلی را درنظر بگیرید. اینبار می‌خواهیم دو ردیف را به آن اضافه کنیم:
facid: 9, Name: 'Spa', membercost: 20, guestcost: 30, initialoutlay: 100000, monthlymaintenance: 800.
facid: 10, Name: 'Squash Court 2', membercost: 3.5, guestcost: 17.5, initialoutlay: 5000, monthlymaintenance: 80.
معادل کدهای SQL چنین عملی، می‌تواند کوئری زیر باشد:
insert into facilities
    (facid, name, membercost, guestcost, initialoutlay, monthlymaintenance)
    values
        (9, 'Spa', 20, 30, 100000, 800),
        (10, 'Squash Court 2', 3.5, 17.5, 5000, 80);
و روش انجام آن در EF-Core تفاوتی با مثال قبلی ندارد:
context.Facilities.Add(new Facility
                {
                    Name = "Spa",
                    MemberCost = 20,
                    GuestCost = 30,
                    InitialOutlay = 100000,
                    MonthlyMaintenance = 800
                });

context.Facilities.Add(new Facility
                {
                    Name = "Squash Court 2",
                    MemberCost = 3.5M,
                    GuestCost = 17.5M,
                    InitialOutlay = 5000,
                    MonthlyMaintenance = 80
                });
context.SaveChanges();
در اینجا می‌توان به هر تعدادی که نیاز است وهله‌های جدیدی از Facility را به context افزودن و سپس SaveChanges را در آخر کار فراخوانی کرد. اینکه EF-Core دستورات insert معادل را به یکباره و یا به صورت مجزایی اجرا می‌کند، به مفهومی به نام batching مرتبط است. اطلاعات بیشتر


مثال 3: افزودن اطلاعات محاسبه شده به یک جدول بانک اطلاعاتی

اطلاعات زیر را درنظر بگیرید:
Name: 'Spa', membercost: 20, guestcost: 30, initialoutlay: 100000, monthlymaintenance: 800.
در مثال اصلی عنوان شده که می‌خواهیم ID آن‌را یکی بیشتر از ردیف قبلی ثبت کنیم. در EF-Core و تنظیمات موجودیت‌هایی که داریم:
namespace EFCorePgExercises.Entities
{
    public class FacilityConfiguration : IEntityTypeConfiguration<Facility>
    {
        public void Configure(EntityTypeBuilder<Facility> builder)
        {
            builder.HasKey(facility => facility.FacId);
            builder.Property(facility => facility.FacId).IsRequired().UseIdentityColumn(seed: 0, increment: 1);
چون ستون ID به صورت خود افزایش یابنده معرفی شده‌است که از صفر شروع می‌شود و به صورت خودکار توسط بانک اطلاعاتی یکی یکی افزایش می‌یابد، نیازی به حل این مساله وجود ندارد. چون ID افزایش یابنده را خود بانک اطلاعاتی محاسبه می‌کند. همچنین به همین علت در مثال‌های قبلی نیز ID را به صورت مستقیمی مقدار دهی نکردیم. اگر نیاز به انجام چنین کاری وجود داشته باشد (ذکر صریح ID خاصی)، با توجه به طراحی بانک اطلاعاتی حاصل از این تنظیمات:
CREATE TABLE [dbo].[Facilities](
[FacId] [int] IDENTITY(0,1) NOT NULL,
--- ...
 CONSTRAINT [PK_Facilities] PRIMARY KEY CLUSTERED 
(
[FacId] ASC
);
باید مانند مثال ثبت اطلاعات اولیه‌ی در بانک اطلاعاتی در قسمت اول این سری، از روش SET IDENTITY_INSERT Facilities ON استفاده کرد تا بتوان مجوز ثبت دستی این ID کنترل شده‌ی توسط بانک اطلاعاتی را پیدا کرد.


مثال 4: به روز رسانی اطلاعاتی از پیش موجود

می‌خواهیم مقدار InitialOutlay دومین زمین تنیس را از 8000 موجود به 10000 تغییر دهیم. با توجه به اینکه ID این زمین شماره 1 است، در حالت متداول SQL نویسی، به کدهای زیر خواهیم رسید:
update facilities
    set initialoutlay = 10000
    where facid = 1;
که معادل EF-Core آن به صورت زیر است:
var facility1 = context.Facilities.Find(1);
facility1.InitialOutlay = 10000;
context.SaveChanges();
این دستورات کوئری مشابهی را تولید نمی‌کنند. ابتدا موجودیت متناظر با ID شماره‌ی 1 از بانک اطلاعاتی واکشی شده و سپس مقدار خاصیتی از آن تغییر کرده‌است. در آخر SaveChanges بر روی آن فراخوانی می‌شود.
EF-Core برای اینکه بتواند تغییرات اعمالی به یک شیء را محاسبه کند، نیاز دارد تا آن شیء را به نحوی در سیستم change tracking خودش موجود داشته باشد. هر نوع کوئری که در EF-Core نوشته می‌شود و به همراه متد AsNoTracking نیست، خروجی تک تک اشیاء حاصل از آن پیش از ارائه‌ی نهایی، وارد سیستم change tracking آن می‌شوند. یعنی اگر مقادیر خواص این اشیاء را تغییر داده و بر روی آن‌ها SaveChanges را فراخوانی کنیم، کوئری‌های متناظر با به روز رسانی تنها این خواص تغییر یافته به صورت خودکار محاسبه شده و به بانک اطلاعاتی اعمال می‌شوند.
فراخوانی متد AsNoTracking بر روی کوئری‌های EF-Core، تولید پروکسی‌های change tracking را غیرفعال می‌کند. یک چنین کوئری‌هایی صرفا کاربردهای گزارشگیری فقط خواندنی را دارند و نسبت به کوئری‌های معمولی، سریعتر و با مصرف حافظه‌ی کمتری هستند. بنابراین نتایج حاصل از کوئری‌های متداول EF-Core، به صورت پیش‌فرض (یعنی بدون داشتن متد AsNoTracking) هم خواندنی و هم نوشتنی با قابلیت اعمال به بانک اطلاعاتی هستند.


مثال 5: به روز رسانی چندین ردیف و چندین جدول در یک زمان

می‌خواهیم مقادیر MemberCost  و GuestCost دو زمین تنیس را به 6 و 30 تغییر دهیم. روش انجام اینکار با SQL نویسی معمولی به صورت زیر است:
update cd.facilities
    set
        membercost = 6,
        guestcost = 30
    where facid in (0,1);
اما همانطور که عنوان شد در EF-Core ابتدا باید اشیاء متناظر با این زمین‌های تنیس را در سیستم change tacking موجود داشت و سپس نسبت به ویرایش آن‌ها اقدام نمود. یکی از روش‌های وارد کردن اشیاء به سیستم change tacking، نوشتن کوئری‌های بدون متد AsNoTracking است و سپس به روز رسانی نتایج حاصل از آن‌ها که اکنون توسط پروکسی‌های change tracking محصور شده‌اند و در آخر فراخوانی SaveChanges بر روی context جاری:
int[] facIds = { 0, 1 };
var tennisCourts = context.Facilities.Where(x => facIds.Contains(x.FacId)).ToList();
foreach (var tennisCourt in tennisCourts)
{
     tennisCourt.MemberCost = 6;
     tennisCourt.GuestCost = 30;
}

context.SaveChanges();


مثال 6: به روز رسانی اطلاعات یک ردیف بر اساس اطلاعات ردیفی دیگر

می‌خواهیم هزینه‌ی دومین زمین تنیس را به نحوی ویرایش کنیم که 10 درصد بیشتر از هزینه‌ی اولین زمین تنیس باشد.
روش پیشنهادی انجام اینکار با SQL نویسی مستقیم به صورت زیر است:
update cd.facilities facs
    set
        membercost = (select membercost * 1.1 from cd.facilities where facid = 0),
        guestcost = (select guestcost * 1.1 from cd.facilities where facid = 0)
    where facs.facid = 1;
در EF-Core می‌توان اشیاء متناظر با این دو زمین تنیس را ابتدا واکشی کرد، سپس تغییر داد و در نهایت ذخیره کرد:
var fac0 = context.Facilities.Where(x => x.FacId == 0).First();
var fac1 = context.Facilities.Where(x => x.FacId == 1).First();
fac1.MemberCost = fac0.MemberCost * 1.1M;
fac1.GuestCost = fac0.GuestCost * 1.1M;

context.SaveChanges();


مثال 7: حذف تمام اطلاعات یک جدول

می‌خواهیم تمام اطلاعات جدول bookings را حذف کنیم.
روش انجام اینکار با SQL نویسی مستقیم به صورت زیر است:
delete from bookings
اما ... این تک کوئری، معادلی را در EF-Core استاندارد ندارد. چون EF-Core نیاز دارد مدام تمام اطلاعات ویرایشی/حذف و به روز رسانی را در context و سیستم change tracking خودش داشته باشد، ابتدا باید توسط یک کوئری لیست اشیاء مدنظر را تهیه کرد و سپس آن‌را به متد RemoveRange معرفی کرد تا حذف تک تک آن‌ها که شامل صدها کوئری خواهد شد، صورت گیرد:
context.Bookings.RemoveRange(context.Bookings.ToList());
context.SaveChanges();
این روش سریع نیست؛ اما کار می‌کند!
البته هستند کتابخانه‌های ثالثی (^ و ^) که انجام به روز رسانی دسته‌ای و یا حذف دسته‌ای از رکوردها را تنها با یک کوئری SQL میسر می‌کنند؛ اما ... هنوز جزئی از EF استاندارد نشده‌اند و مهم‌ترین مشکل احتمالی این روش‌ها، همگام نبودن context و سیستم change tacking، با نتیجه‌ی حاصل از به روز رسانی یکباره‌ی صدها ردیف است.



مثال 8: حذف یک کاربر از جدول کاربران

می‌خواهیم کاربر شماره‌ی 37 را حذف کنیم.
روش انجام اینکار با SQL نویسی به صورت زیر است:
delete from members where memid = 37;
و در EF-Core برای انجام اینکار می‌توان ابتدا شیء متناظر با کاربر 37 را از طریق یک کوئری به سیستم change tracking وارد کرد و سپس آن‌را حذف نمود:
var mem37 = context.Members.Where(x => x.MemId == 37).First();
context.Members.Remove(mem37);

context.SaveChanges();

یک نکته: امکان ساده‌تر حذف یک ردیف با داشتن ID آن

کوئری گرفتن از بانک اطلاعاتی، یک روش وارد کردن شیءای به context و سیستم change tacking آن است. در این حالت عموما فرض بر این است که ID شیء را نمی‌دانیم. اما اگر این ID مانند مثال جاری از پیش مشخص بود، نیازی نیست تا ابتدا از بانک اطلاعاتی کوئری گرفت و کل شیء را در حافظه وارد کرد. در این حالت خاص می‌توان با استفاده از روش زیر، این ID را وارد سیستم tracking کرد و سپس حالت آن‌را به Deleted تغییر داد و در آخر آن‌را ذخیره کرد:
var entry = context.Entry(new Member { MemId = 37 });
entry.State = EntityState.Deleted;
context.SaveChanges();
در کدهای فوق می‌توان سطر entry.State = EntityState.Deleted را با context.Remove(entry) نیز جایگزین کرد و هر دو به یک معنا هستند.
روش فوق چنین کوئری‌هایی را ایجاد می‌کند:
SET NOCOUNT ON;
DELETE FROM [Members]
WHERE [MemId] = @p0;
SELECT @@ROWCOUNT;


مثال 9: حذف بر اساس یک sub-query

می‌خواهیم تمام کاربرانی را که هیچگاه رزروی را انجام نداده‌اند، حذف کنیم.
این مورد نیز با SQL نویسی مستقیم نیز توسط یک کوئری دسته‌ای قابل انجام است:
delete from members where memid not in (select memid from cd.bookings);
اما همانطور که عنوان شد، EF-Core این نوع اعمال ویرایش دسته‌ای را در طی یک تک کوئری پشتیبانی نمی‌کند. به همین جهت ابتدا آن‌ها را توسط یک کوئری به context وارد کرده و سپس حذف می‌کنیم:
var mems = context.Members.Where(x =>
  !context.Bookings.Select(x => x.MemId).Contains(x.MemId)).ToList();
context.Members.RemoveRange(mems);

context.SaveChanges();


کدهای کامل این قسمت را در اینجا می‌توانید مشاهده کنید.
نظرات مطالب
شروع به کار با EF Core 1.0 - قسمت 14 - لایه بندی و تزریق وابستگی‌ها
- این خطا یعنی سرویس IConfigurationRoot را به سیستم تزریق وابستگی‌ها معرفی نکردید.
- تنظیمات اولیه‌ی EF Core از زمان نگارش 2 آن اندکی تغییر کرده؛ خلاصه‌ی نهایی و به روز شده‌ی آن در پروژه‌ی DNTIdentity و یا پروژه‌ی «اعتبارسنجی مبتنی بر JWT در ASP.NET Core 2.0 بدون استفاده از سیستم Identity» موجود است (هر دو پروژه به آخرین نگارش SDK، به روز رسانی شده‌اند).
مطالب
Minimal API's در دات نت 6 - قسمت اول - معرفی
یکی از مهم‌ترین تغییرات دات نت 6، ارائه‌ی Minimal API's به همراه آن است که نسبت به MVC و سایر مشتقات ASP.NET Core، کمتر به همراه پیش‌فرض‌های نظری خاص و بسیار مقید و متعصبانه (opinionated) است؛ که این مورد خود مزیتی است جهت انجام امور متداول، به نحوی دیگر و دلخواه و با آزادی عمل بیشتری در طراحی endpoints مورد نیاز و کل برنامه. خصوصا این سبک جدید، با معماری برش‌های عمودی (vertical slices) ارائه شده‌ی توسط نویسنده‌ی AutoMapper، هماهنگی خاصی دارد و اینطور به نظر می‌رسد که جهت ساده سازی طراحی برنامه‌های ASP.NET Core با معماری CQRS ارائه شده‌است. با وجود Minimal API's می‌توان از دو لایه‌ی متداول برنامه‌ها رها شد: لایه‌ی سرویس‌ها و لایه‌ی مخازن یا Repositories. در معماری برش‌های عمودی، برنامه به ویژگی‌های خاصی (Features) تقسیم شده و هر ویژگی، متکی به خود طراحی می‌شود. زمانیکه از هندلرها برای هر Command و Query معماری CQRS استفاده می‌کنیم، این‌ها مختص به یک ویژگی متکی به خود طراحی می‌شوند و به همراه تمام اطلاعات و اعمال مرتبط هستند و دیگر در این حالت، وجود لایه‌های سرویس و مخزن، بی‌معنا و غیرضروری می‌شوند.

در ادامه قصد داریم تمام این موارد را مانند Minimal API's و معماری برش‌های عمودی به همراه CQRS، در طی یک سری و یک پروژه‌ی عملی ساخت یک Blog به نام MinimalBlog، بررسی کنیم. البته هدف ما در اینجا صرفا ساخت backend ساختار یافته‌ی این برنامه‌است؛ منهای UI آن. هدف اصلی ما از این سری، ارائه‌ی یک معماری، جهت کار با Minimal API's است.


دریافت کدهای کامل این سری

جهت مرور سریعتر و ساده‌تر این سری، کدهای کامل آن‌را از اینجا می‌توانید دریافت کنید: MinimalBlog.zip


پروژه‌هایی که برنامه‌ی MinimalBlog را تشکیل می‌دهند

برنامه‌ی MinimalBlog، تنها از سه پروژه‌ی زیر تشکیل می‌شود:
MinimalBlog.Api: این پروژه از نوع minimal API's است که توسط دستور جدید «dotnet new webapi --use-minimal-apis» آغاز خواهد شد و به صورت پیش‌فرض به همراه پشتیبانی از OpenAPI نیز هست. البته اگر از VS2022 استفاده می‌کنید، در حین آغاز یک پروژه‌ی Web API جدید، تیک مربوط به use controllers را در UI بردارید تا از Minimal API's استفاده شود.
MinimalBlog.Dal: که Dal در اینجا مخفف data access layer است و یک class library می‌باشد و با دستور dotnet new classlib آغاز می‌شود.
MinimalBlog.Domain: نیز یک class library است و با دستور dotnet new classlib آغاز می‌شود.

همانطور که مشاهده می‌کنید، این طراحی جدید، بدون وجود لایه‌ی متداول سرویس‌ها و یا مخازن است.


بررسی ساختار ابتدایی پروژه‌ی MinimalBlog.Api

در اینجا تنها تک فایل Program.cs، به همراه تنظیمات برنامه قابل مشاهده‌است و فایل Starup.cs از آن حذف شده‌است (اطلاعات بیشتر). این فایل نیز بر مبنای مفهوم top level programs طراحی شده‌است و به همراه تعریف class و یا فضای نامی نیست:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
همانطور که ملاحظه می‌کنید، تمام اتفاقات در همین تک فایل رخ می‌دهند. برای مثال سرویس‌های مورد نیاز برنامه به مجموعه‌ی builder.Services اضافه می‌شوند؛ شبیه به کاری که پیشتر در فایل Startup.cs و متد ConfigureServices آن انجام می‌دادیم.

پس از آن به تعاریف زیر می‌رسیم؛ تعاریف میان افزارهایی که پیشتر در متد Configure کلاس Startup انجام می‌شدند، الان همگی در تک فایل Program.cs قرار دارند:
var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
البته هنوز هم می‌توان در صورت نیاز به همان ساختار کلاس Startup پیشین نیز رسید.


در انتهای این فایل نیز تعاریف پیش‌فرض زیر قرار دارند:
var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

app.MapGet("/weatherforecast", () =>
{
    var forecast =  Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateTime.Now.AddDays(index),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast");

app.Run();

record WeatherForecast(DateTime Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
در اینجا متد متد MapGet یک endpoint را تعریف کرده و سپس اکشنی را به آن انتساب می‌دهد. یعنی اگر آدرس weatherforecast/ درخواست شود، lambda expression تعریف شده، اجرا می‌شود. هدف از ارائه‌ی Minimal API نیز همین است تا بتوان با حداقل کدنویسی، سریعا به نتیجه‌ی مدنظر خود رسید.
در همین حال اگر برنامه‌ی Api را اجرا کنیم، به تصویر زیر خواهیم رسید:


در ادامه کدهای موجود در این فایل را Refactor کرده و به کلاس‌های دیگری منتقل می‌کنیم؛ چون اگر قرار باشد در طول زمان تمام endpoints مدنظر را در همینجا تعریف کنیم، کنترل برنامه از دست خارج خواهد شد.


غنی سازی Solution و کامپایلر #C با استفاده از فایل‌های editorconfig. و Directory.Build.props

در مورد این دو فایل در مطلب «غنی سازی کامپایلر C# 9.0 با افزونه‌ها » بیشتر بحث شده‌است. هدف از آن‌ها، اعمال یکسری تنظیمات سراسری، به تمام پروژه‌های یک solution به صورت یک‌دست است؛ مانند تنظیمات کامپایلر جهت نمایش اخطارها به صورت خطاها، تعریف usingهای سراسری سی‌شارپ 10 و یا اعمال Roslyn analyzers به تمام پروژه‌ها. این دو فایل را به همراه پروژه‌ی پیوست می‌توانید دریافت کنید و ... باید جزء استاندارد تمام پروژه‌های جدید باشند. چون وجود آن‌ها سبب خواهد شد که به شدت کیفیت کدهای نهایی افزایش یابند و مبتنی بر یکسری best practices شوند.
اشتراک‌ها
پیاده سازی یک پروژه با ASP.NET Core Web API و Angular

Learn FULL STACK Web Development in 2 HOURS! ASP.NET & Angular

Timestamps:
00:00:00 Welcome to our 2 hour FULL STACK Course!
00:01:12 What you will learn during the next 2 hours
00:03:29 Day 1 Multi-Page and Single-Page Applications, TypeScript, and Angular Components
00:21:57 Day 2 One-Way Binding and Event Binding in Angular
00:34:23 Day 3 Our Flight Booking Portal and routing in Angular
00:44:52 Day 4 The 'Search Flight' page, Design a HTML page, install Font Awesome using Node, and TypeScript interfaces
01:27:00 Day 5 ASP.NET Core REST API, SWAGGER for documenting and testing our API
01:55:51 Thanks for watching!
 

پیاده سازی یک پروژه با ASP.NET Core Web API و Angular
نظرات مطالب
امن سازی برنامه‌های ASP.NET Core توسط IdentityServer 4x - قسمت ششم - کار با User Claims
Claim type: http://schemas.microsoft.com/claims/authnmethodsreferences - Claim value: pwd
Claim type: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier - Claim value: 1
Claim type: auth_time - Claim value: 1651417673
Claim type: http://schemas.microsoft.com/identity/claims/identityprovider - Claim value: local
Claim type: name - Claim value: meysanm
Claim type: given_name - Claim value: soleymani
Claim type: role - Claim value: admin
Claim type: http://schemas.microsoft.com/claims/authnmethodsreferences - Claim value: pwd
Claim type: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier - Claim value: 1
Claim type: auth_time - Claim value: 1651417673
Claim type: http://schemas.microsoft.com/identity/claims/identityprovider - Claim value: local
Claim type: name - Claim value: meysanm
Claim type: given_name - Claim value: soleymani
Claim type: role - Claim value: admin
اشتراک‌ها
تغییر نام رسمی ASP.NET 5 و EF 7

Reintroducing ASP.NET Core 1.0 and .NET Core 1.0

ASP.NET 5 is now ASP.NET Core 1.0.
.NET Core 5 is now .NET Core 1.0.
Entity Framework 7 is now Entity Framework Core 1.0 or EF Core 1.0 colloquially.
 

تغییر نام رسمی ASP.NET 5 و EF 7