مسیرراه‌ها
ASP.NET Core
ASP.NET Core 1.0
ASP.NET Core 2.0
روش ارتقاء
ASP.NET Core Identity 

کار با 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 
نمایش خطاهای اعتبارسنجی سمت سرور ASP.NET Core در برنامه‌های Angular
احراز هویت و اعتبارسنجی کاربران در برنامه‌های Angular - قسمت اول - معرفی و ایجاد ساختار برنامه
روش استفاده‌ی صحیح از HttpClient در برنامه‌های دات نت
اجرای سرویسهای NodeJS در ASP.NET Core
بررسی خطاهای ممکن در حین راه اندازی اولیه برنامه‌های ASP.NET Core در IIS 
تست کردن متدهای یک Controller به کمک PowerShell
کار با Visual Studio در ASP.NET Core

مطالب
بررسی روش ارتقاء به NET Core 1.1.
نگارش پایدار NET Core 1.1. روز قبل منتشر شد. در ادامه نحوه‌ی ارتقاء پروژه‌‌های نگارش 1.0 RTM را به این نگارش بررسی خواهیم کرد.


دریافت نصاب NET Core 1.1.

برای این منظور به آدرس https://www.microsoft.com/net/download/core مراجعه کرده و فایل NET Core 1.1 SDK - Installer. را دریافت و نصب کنید. برای ظاهر شدن این گزینه باید حالت Current را بجای LTS (Long Term Support) انتخاب کرد:


همچنین در اینجا بسته NET Core 1.1 runtime - Installer. را هم جداگانه می‌توان دریافت و نصب کرد.


به روز رسانی فایل‌های global.json پروژه‌ها

اولین کاری را که باید پس از نصب نگارش‌های جدید NET Core. انجام داد، به روز رسانی شماره نگارش SDK درج شده‌ی در فایل‌های global.json تمام پروژه‌های موجود است. در غیراینصورت NuGet بسته‌های جدید مرتبط با آن‌ها را دریافت نخواهد کرد و آن‌ها را در لیست به روز شده‌ها نخواهید یافت.
برای این منظور خط فرمان را گشوده و دستور ذیل را صادر کنید:
 C:\>dotnet --version
1.0.0-preview2-1-003177
خروجی آن عبارتی است که باید قسمت نگارش SDK درج شود:
{
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-preview2-1-003177"
  }
}


اصلاح فایل project.json پس از به روز رسانی فایل global.json

در ادامه باید فایل project.json نیز اندکی ویرایش شود تا شماره platform جدید را نیز درج کند. همچنین محل قرارگیری یکسری از بسته‌ها نیز باید تغییر کنند. در غیر اینصورت با اولین کامپایل Solution چنین خطاهایی را دریافت خواهید کرد:
 Can not find runtime target for framework '.NETCoreApp,Version=v1.0' compatible with one of the target runtimes: 'win10-x64, win81-x64, win8-x64, win7-x64'.
The project does not list one of 'win10-x64, win81-x64, win8-x64, win7-x64' in the 'runtimes' section.
برای رفع این مشکل، عبارت netcoreapp را در Solution جاری جستجو کرده و آن‌ها را به نحو ذیل تغییر دهید:
"frameworks": {
    "netcoreapp1.1": {
        "dependencies": {
            "Microsoft.NETCore.App": {
                "type": "platform",
                "version": "1.1.0"
            }
        },
        "imports": [
            "dnxcore50",
            "portable-net45+win8"
        ]
    }
},

یک نکته: اگر هنوز Microsoft.NETCore.App را در لیست dependencies ابتدای فایل project.json دارید، آن‌را حذف کنید؛ چون در قسمت frameworks فوق درج شده‌است. در غیراینصورت پیام تکراری بودن این کلید را دریافت خواهید کرد.

پس از طی دو مرحله‌ی فوق، یکبار پروژه را بسته و مجددا باز کنید.


به روز رسانی بسته‌های نیوگت پایدار

قبل از هر کاری مطمئن شوید که آخرین بسته‌ی خود NuGet را نیز نصب کرده‌اید (مهم). به روز رسانی‌های اخیر آن بیشتر در جهت سازگاری با پروژه‌های NET Core. است.
https://dist.nuget.org/index.html

در ادامه برای به روز رسانی بسته‌های نیوگت، می‌توان بر روی گره References کلیک راست کرد و سپس انتخاب گزینه‌ی Manage NuGet Packages و در آخر انتخاب برگه‌ی Updates و انتخاب کتابخانه‌های به روز شده. این روش برای حالت داشتن چندین پروژه در یک Solution اندکی کند است.


روش سریعتر که تمام پروژه‌ها را نیز به صورت خودکار بررسی و به روز می‌کند، مراجعه به کنسول پاورشل نیوگت و سپس صدور دستور ذیل است:
 PM> Update-Package
اگر در میان کار خطایی را دریافت کردید، این دستور را مجددا اجرا کنید (جهت اطمینان حداقل دوبار این دستور را صادر کنید).
به علاوه پس از پایان کار، یکبار به طور کامل ویژوال استودیو را بسته و مجددا باز کنید. سپس این دستور را یکبار دیگر هم صادر کنید.


به روز رسانی بسته‌های نیوگت آزمایشی

یکسری از بسته‌ها مانند Microsoft.AspNetCore.Razor.Tools تنها با انتخاب حالت include prereleases ظاهر می‌شوند که آن‌ها را نیز باید به روز کرد:



تغییر مهم ابزارهای EF Core

در کل Solution عبارت Microsoft.EntityFrameworkCore.Tools را جستجو کرده و با نام جدید Microsoft.EntityFrameworkCore.Tools.DotNet جایگزین کنید.


در آخر یک نمونه فایل project.json به روز شده‌ی یک برنامه‌ی ASP.NET Core 1.1 را در ذیل مشاهده می‌کنید:
{
    "dependencies": {
        "Microsoft.AspNetCore.Diagnostics": "1.1.0",
        "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.1.0",
        "Microsoft.AspNetCore.Http.Extensions": "1.1.0",
        "Microsoft.AspNetCore.Mvc": "1.1.0",
        "Microsoft.AspNetCore.Mvc.Core": "1.1.0",
        "Microsoft.AspNetCore.Mvc.TagHelpers": "1.1.0",
        "Microsoft.AspNetCore.Razor.Runtime": "1.1.0",
        "Microsoft.AspNetCore.Razor.Tools": {
            "version": "1.1.0-preview4-final",
            "type": "build"
        },
        "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
        "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
        "Microsoft.AspNetCore.Session": "1.1.0",
        "Microsoft.AspNetCore.SpaServices": "1.0.0-beta-000019",
        "Microsoft.AspNetCore.StaticFiles": "1.1.0",
        "Microsoft.EntityFrameworkCore": "1.1.0",
        "Microsoft.EntityFrameworkCore.InMemory": "1.1.0",
        "Microsoft.EntityFrameworkCore.Tools.DotNet": {
            "version": "1.1.0-preview4-final",
            "type": "build"
        },
        "Microsoft.Extensions.Configuration.Binder": "1.1.0",
        "Microsoft.Extensions.Configuration.Json": "1.1.0",
        "Microsoft.Extensions.Logging.Console": "1.1.0",
        "Microsoft.Extensions.Logging.Debug": "1.1.0",
        "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
            "version": "1.1.0-preview4-final",
            "type": "build"
        },
        "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
            "version": "1.1.0-preview4-final",
            "type": "build"
        }
    },
 
    "tools": {
        "BundlerMinifier.Core": "2.2.301",
        "Microsoft.AspNetCore.Razor.Tools": "1.1.0-preview4-final",
        "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
            "version": "1.1.0-preview4-final",
            "imports": [
                "portable-net45+win8"
            ]
        },
        "Microsoft.EntityFrameworkCore.Tools.DotNet": {
            "version": "1.1.0-preview4-final",
            "imports": [
                "portable-net45+win8"
            ]
        },
        "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final"
    },
 
    "frameworks": {
        "netcoreapp1.1": {
            "dependencies": {
                "Microsoft.NETCore.App": {
                    "type": "platform",
                    "version": "1.1.0"
                }
            },
            "imports": [
                "dnxcore50",
                "portable-net45+win8"
            ]
        }
    },
 
    "buildOptions": {
        "emitEntryPoint": true,
        "preserveCompilationContext": true
    },
 
    "runtimeOptions": {
        "configProperties": {
            "System.GC.Server": true
        }
    },
 
    "publishOptions": {
        "include": [
            "wwwroot",
            "Features",
            "appsettings.json",
            "web.config"
        ]
    },
 
    "configurations": {
        "Release": {
            "buildOptions": {
                "optimize": true,
                "platform": "anycpu"
            }
        }
    },
 
    "scripts": {
        "precompile": [
            "dotnet bundle"
        ],
        "prepublish": [
            //"bower install"
        ],
        "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
    }
}


به روز رسانی پروژه‌ی Test

اگر از MSTest برای انجام آزمون‌های واحد استفاده می‌کنید، تغییرات فایل project.json آن نیز شامل تغییر شماره نگارش NETStandard.Library به 1.6.1 است و همچنین خود بسته‌های mstest نیز به روز شده‌اند. به علاوه قسمت frameworks آن نیز باید همانند مطالبی که عنوان شد، به روز شود:
{
    "version": "1.0.0-*",
 
    "testRunner": "mstest",
    "dependencies": {
        "Microsoft.EntityFrameworkCore": "1.1.0",
        "Microsoft.EntityFrameworkCore.InMemory": "1.1.0",
        "NETStandard.Library": "1.6.1",
        "dotnet-test-mstest": "1.1.2-preview",
        "MSTest.TestFramework": "1.0.6-preview"
    },
 
    "frameworks": {
        "netcoreapp1.1": {
            "dependencies": {
                "Microsoft.NETCore.App": {
                    "type": "platform",
                    "version": "1.1.0"
                }
            },
            "imports": [
                "dnxcore50",
                "portable-net45+win8"
            ]
        }
    }
}
مطالب
معرفی System.Text.Json در NET Core 3.0.
معروفترین کتابخانه‌ی کار با JSON در دات نت، Json.NET است که این روزها، جزء جدایی ناپذیر حداقل، تمام برنامه‌های وب مبتنی بر دات نت می‌باشد. برای مثال ASP.NET Core 2x/1x و همچنین ASP.NET Web API پیش از NET Core.، به صورت پیش‌فرض از این کتابخانه برای کار با JSON استفاده می‌کنند. این کتابخانه 10 سال پیش ایجاد شد و در طول زمان، قابلیت‌های زیادی به آن اضافه شده‌است. همین حجم بالای کار صورت گرفته سبب شده‌است که برای مثال شروع به استفاده‌ی از <Span<T در آن برای بالابردن کارآیی، بسیار مشکل شده و نیاز به تغییرات اساسی در آن داشته باشد. به همین جهت خود تیم CoreFX دات نت Core گزینه‌ی دیگری را برای کار با JSON در فضای نام جدید System.Text.Json ارائه داده‌است که برای کار با آن نیاز به نصب وابستگی ثالثی نیست و همچنین کارآیی آن به علت استفاده‌ی از ویژگی‌های جدید زبان، مانند ref struct و Span، به طور میانگین دو برابر کتابخانه‌ی Json.NET است. برای مثال استفاده‌ی از string (حالت پیش‌فرض کتابخانه‌ی Json.NET) یعنی کار با رشته‌هایی از نوع UTF-16؛ اما کار با Span، امکان دسترسی مستقیم به رشته‌هایی از نوع UTF-8 را میسر می‌کند که نیازی به تبدیل به رشته‌هایی از نوع UTF-16 را ندارند.


ASP.NET Core 3x دیگر به صورت پیش‌فرض به همراه Json.NET ارائه نمی‌شود

در برنامه‌های ASP.NET Core 3x، وابستگی ثالث Json.NET حذف شده‌است و از این پس هر نوع خروجی JSON آن، مانند بازگشت مقادیر مختلف از اکشن متدهای کنترلرها، به صورت خودکار در پشت صحنه از امکانات ارائه شده‌ی در System.Text.Json استفاده می‌کند و دیگر Json.NET، کتابخانه‌ی پیش‌فرض کار با JSON آن نیست. بنابراین برای کار با آن نیاز به تنظیم خاصی نیست. همینقدر که یک پروژه‌ی جدید ASP.NET Core 3x را ایجاد کنید، یعنی در حال استفاده‌ی از System.Text.Json هستید.


روش بازگشت به Json.NET در ASP.NET Core 3x

اگر به هر دلیلی هنوز نیاز به استفاده‌ی از کتابخانه‌ی Json.NET را دارید، آداپتور ویژه‌ی آن نیز تدارک دیده شده‌است. برای اینکار:
الف) ابتدا باید بسته‌ی نیوگت Microsoft.AspNetCore.Mvc.NewtonsoftJson را نصب کنید.
ب) سپس در کلاس Startup، باید این کتابخانه را به صورت یک سرویس جدید، با فراخوانی متد AddNewtonsoftJson، معرفی کرد:
 public void ConfigureServices(IServiceCollection services)
 {
     services.AddControllers()
            .AddNewtonsoftJson()
     // ...
}
یکی از دلایل بازگشت به Json.NET می‌تواند عدم پشتیبانی از OpenAPI / Swagger در حین کار با System.Text.Json باشد و این مورد قرار نیست در نگارش نهایی 3.0، حضور داشته باشد و انطباق با آن به نگارش‌های بعدی موکول شده‌است.


روش کار مستقیم با System.Text.Json

اگر در قسمتی از برنامه‌ی خود نیاز به کار مستقیم با اشیاء JSON را داشته باشید و یا حتی بخواهید از این قابلیت در برنامه‌های کنسول و یا کتابخانه‌ها نیز استفاده کنید، روش انتقال کدهایی که از Json.NET استفاده می‌کنند به System.Text.Json، به صورت زیر است:
public class Person
{
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public DateTime? BirthDay { get; set; }
}
تبدیل رشته‌ی JSON حاوی اطلاعات شخص، به شیء متناظر با آن و یا حالت عکس آن:
using System;
using System.Text.Json.Serialization;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Person person = JsonSerializer.Parse<Person>(...);
            string json = JsonSerializer.ToString(person);
        }
    }
}
در اینجا از کلاس System.Text.Json.Serialization.JsonSerializer، روش کار با دو متد Parse را برای Deserialization و ToString را برای Serialization مشاهده می‌کنید.
کلاس JsonSerializer دارای overloadهای زیر برای کار با متدهای Parse و ToString است:
namespace System.Text.Json.Serialization
{
    public static class JsonSerializer
    {
        public static object Parse(ReadOnlySpan<byte> utf8Json, Type returnType, JsonSerializerOptions options = null);
        public static object Parse(string json, Type returnType, JsonSerializerOptions options = null);
        public static TValue Parse<TValue>(ReadOnlySpan<byte> utf8Json, JsonSerializerOptions options = null);
        public static TValue Parse<TValue>(string json, JsonSerializerOptions options = null);

        public static string ToString(object value, Type type, JsonSerializerOptions options = null);
        public static string ToString<TValue>(TValue value, JsonSerializerOptions options = null);
    }
}
یک نکته: کارآیی متد Parse با امضای ReadOnlySpan<byte> utf8Json، بیشتر است از نمونه‌ای که string json را می‌پذیرد. از این جهت که چون با آرایه‌ای از بایت‌های رشته‌ای از نوع UTF-8 کار می‌کند، نیاز به تبدیل به UTF-16 را مانند متدی که string را می‌پذیرد، ندارد. برای تولید آرایه‌ی بایت‌های utf8Json از روی یک شیء، می‌توانید از متد JsonSerializer.ToUtf8Bytes استفاده کنید و یا برای تولید آن از روی یک رشته، از متد Encoding.UTF8.GetBytes استفاده کنید.


سفارشی سازی JsonSerializer جدید

اگر به امضای متدهای Parse و ToString کلاس JsonSerializer دقت کنید، دارای یک پارامتر اختیاری از نوع JsonSerializerOptions نیز هستند که به صورت زیر تعریف شده‌است:
public sealed class JsonSerializerOptions
{
   public bool AllowTrailingCommas { get; set; }
   public int DefaultBufferSize { get; set; }
   public JsonNamingPolicy DictionaryKeyPolicy { get; set; }
   public bool IgnoreNullValues { get; set; }
   public bool IgnoreReadOnlyProperties { get; set; }
   public int MaxDepth { get; set; }
   public bool PropertyNameCaseInsensitive { get; set; }
   public JsonNamingPolicy PropertyNamingPolicy { get; set; }
   public JsonCommentHandling ReadCommentHandling { get; set; }
   public bool WriteIndented { get; set; }
}
برای نمونه معادل تنظیم NullValueHandling در Json.NET:
// Json.NET:
var settings = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore
};
string json = JsonConvert.SerializeObject(person, settings);
اینبار توسط خاصیت IgnoreNullValues صورت می‌گیرد:
// JsonSerializer:
var options = new JsonSerializerOptions
{
    IgnoreNullValues = true
};
string json = JsonSerializer.ToString(person, options);

در برنامه‌های ASP.NET Core که این نوع متدها در پشت صحنه فراخوانی می‌شوند، روش تنظیم JsonSerializerOptions به صورت زیر است:
services.AddControllers()
   .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);


نگاشت نام ویژه‌ی خواص در حین عملیات deserialization

در مثال فوق، فرض شده‌است که نام خاصیت BirthDay، دقیقا با اطلاعاتی که از رشته‌ی JSON دریافتی پردازش می‌شود، تطابق دارد. اگر این نام در اطلاعات دریافتی متفاوت است، می‌توان از ویژگی JsonPropertyName برای تعریف این نگاشت استفاده کرد:
[JsonPropertyName("birthdate")]
public DateTime? BirthDay { get; set; }
روش دیگر اینکار، برای نمونه تنظیم PropertyNamingPolicy به حالت CamelCase است:
var options = new JsonSerializerOptions
{
   PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
string json = JsonSerializer.ToString(person, options);
و یا اگر می‌خواهید حساسیت به بزرگی و کوچکی حروف را ندید بگیرید (مانند حالت پیش‌فرض JSON.NET) از تنظیم JsonSerializerOptions.PropertyNameCaseInsensitive استفاده کنید.

در این بین اگر نمی‌خواهید خاصیتی در عملیات serialization و یا برعکس آن پردازش شود، می‌توان از تعریف ویژگی [JsonIgnore] بر روی آن استفاده کرد.