عنوان:

‫تغییرات ناسازگار با نگارش‌های قبلی در NET 10. که باید هنگام ارتقاء به آن‌ها توجه کرد


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۸/۱۷ ۰۹:۲۳
آدرس: www.dntips.ir
در این مطلب، به بررسی تغییرات کلیدی ناسازگار با نگارش‌های قبلی دات‌نت که در .NET 10 معرفی شده‌اند، می‌پردازیم. هر تغییر را با توضیح دلیل وقوع آن، تأثیر احتمالی بر برنامه‌های شما و راه‌حل‌های پیشنهادی توصیف می‌کنیم. این تغییرات عمدتاً بر رفتار پیش‌فرض سیستم تأثیر می‌گذارند و ممکن است نیاز به تنظیمات کد یا تست‌های اضافی داشته باشند.

غیرفعال شدن هدایت‌های ورود با کوکی برای نقاط پایانی API شناخته‌شده
پایپ‌لاین ASP.NET Core بسیار قابل تنظیم است تا نیازهای متنوعی را برآورده کند. بسیاری از مشتریان Duende، نقاط پایانی API امن‌شده با OAuth را در کنار UIهای MVC یا Razor Pages ترکیب می‌کنند. رفتار رایجی که بسیاری از توسعه‌دهندگان .NET متوجه آن می‌شوند، این است که نقاط پایانی API به طور تصادفی پاسخ چالش (challenge) را فعال می‌کنند و سعی می‌کنند caller را به نمونه IdentityServer هدایت کنند. این رفتار هدایت، چیزی نیست که اکثر توسعه‌دهندگان بخواهند؛ caller احتمالاً انتظار پاسخ 401 Unauthorized یا 403 Forbidden را دارد.
در .NET 10، هر نقطه پایانی که با احراز هویت کوکی امن شده و با رابط IApiEndpointMetadata علامت‌گذاری شده، دیگر به URI ورود یا دسترسی ممنوع هدایت نمی‌شود. این تغییر شامل نقاط پایانی ApiController، نقاط پایانی Minimal API که درخواست‌های JSON ورودی یا پاسخ‌های JSON خروجی را مدیریت می‌کنند، نقاط پایانی با TypedResults، یا نقاط پایانی SignalR می‌شود.
پیشنهاد می‌کنیم در محیط‌های تست، سناریوهای API را با ابزارهایی مانند Postman بررسی کنید تا مطمئن شوید پاسخ‌های مناسب (مانند 401) دریافت می‌شود. اگر برنامه شما به هدایت‌های قدیمی وابسته است، می‌توانید رفتار را با تنظیمات سفارشی middleware بازگردانید، اما این کار را با احتیاط انجام دهید تا امنیت کاهش نیابد.

منسوخ شدن IActionContextAccessor و ActionContextAccessor
.NET اکنون abstractions IActionContextAccessor و ActionContextAccessor را به عنوان منسوخ‌شده (obsolete) علامت‌گذاری کرده‌است.
از آنجایی که ASP.NET Core به Endpoint Routing منتقل شده، می‌توانید هر استفاده از IActionContextAccessor را با HttpContextAccessor یا IHttpContextAccessor جایگزین کنید. کد نمونه زیر نشان‌دهنده این مهاجرت ساده است:
public class MyService
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public MyService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void DoSomething()
    {
        var httpContext = _httpContextAccessor.HttpContext;
        var endpoint = httpContext?.GetEndpoint();
        var actionDescriptor = endpoint?.Metadata.GetMetadata<ActionDescriptor>();

        // استفاده از متادیتای action descriptor.
    }
}
توجه کنید که HttpContext همچنان تنها در طول عمر یک درخواست وب فعال در دسترس است. برای توضیح بیشتر، اگر از این abstractions در کدهای قدیمی استفاده می‌کنید، بررسی کنید که آیا نیاز به دسترسی به متادیتای endpoint دارید؛ در غیر این صورت، این مهاجرت می‌تواند عملکرد برنامه را بهبود بخشد؛ زیرا Endpoint Routing کارآمدتر است.

منسوخ شدن IPNetwork و ForwardedHeadersOptions.KnownNetworks
بسیاری از مشتریان Duende، به ویژه کسانی که از نسخه Enterprise استفاده می‌کنند، به شدت به Forwarded Headers برای استقرار راه‌حل‌های امنیتی متعادل‌شده با بار (load-balanced) وابسته هستند. این نیازمند تنظیم مناسب برنامه‌های ASP.NET Core است، که شامل تنظیم ForwardedHeadersMiddleware و گزینه‌های آن می‌شود.
در .NET 10، هنگام استفاده از KnownNetworks در ForwardedHeadersOptions، هشدار منسوخ بودن دریافت خواهید کرد و به استفاده از KnownIpNetworks هدایت می‌شوید. کد نمونه مهاجرت:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    KnownIpNetworks.Add(new(IPAddress.Loopback, 8))
});
این تغییر به دلیل بهبود امنیت و سازگاری با IPv6 است؛ بنابراین، شبکه‌های شناخته‌شده خود را بررسی کنید تا از پوشش کامل آدرس‌های IP اطمینان حاصل شود.

منسوخ شدن کامپایل زمان اجرا Razor
توسعه‌دهندگان از ویژگی کامپایل زمان اجرا Razor برای ایجاد حلقه بازخورد سریع‌تر استفاده می‌کنند. قبلاً، این ویژگی فایل‌های .cshtml تغییر یافته را در زمان اجرا دوباره کامپایل می‌کرد و از فاز راه‌اندازی کند معمول اجتناب می‌کرد. .NET اکنون متد AddRazorRuntimeCompilation را به عنوان منسوخ علامت‌گذاری کرده و به جای آن، Hot Reload مبتنی بر ابزارها را پیشنهاد می‌کند که در Visual Studio، C# Dev Kit برای VS Code و JetBrains Rider موجود است.
اگر همچنان از این ویژگی استفاده کنید، هشدار زیر را خواهید دید:
warning ASPDEPR003: Razor run-time compilation is obsolete and is not recommended for production scenarios.
For production scenarios, use the default build time compilation. For development scenarios, use Hot Reload instead.
For more information, visit https://aka.ms/aspnet/deprecate/003.
توسعه‌دهندگانی که هشدارها را به عنوان خطا رفع می‌کنند، ممکن است بیلدهایشان شکست بخورد تا این مسئله را حل کنند. برای توضیح کامل‌تر، Hot Reload نه تنها سریع‌تر است بلکه امن‌تر، زیرا تغییرات را بدون راه‌اندازی مجدد اعمال می‌کند؛ بنابراین، مهاجرت به آن را اولویت دهید.

منسوخ شدن WebHostBuilder، IWebHost و WebHost
گر استقرارهای فعلی شما بر اساس قالب‌های گذشته‌است، باید کد را کمی تنظیم کنید تا از این هشدارها اجتناب شود:
warning ASPDEPR004: WebHostBuilder is deprecated in favor of HostBuilder and WebApplicationBuilder.
For more information, visit https://aka.ms/aspnet/deprecate/004.
همان‌طور که پیام اشاره می‌کند، باید از WebHostBuilder به HostBuilder یا WebApplicationBuilder مهاجرت کنید. اگر IWebHost را به عنوان وابستگی تزریق می‌کنید، به IHost سوئیچ کنید یا abstraction هدفمندی برای انتقال اطلاعات مورد نیاز ایجاد کنید. این تغییر بخشی از تلاش برای یکپارچه‌سازی بهتر میزبانی است و می‌تواند برنامه‌های شما را برای محیط‌های ابری آماده‌تر کند.

استفاده از Ubuntu به عنوان پایه پیش‌فرض تصاویر کانتینر .NET
در نسخه‌های قبلی، تصاویر کانتینر .NET بر پایه Debian بودند. از .NET 10، تیم .NET به Ubuntu به عنوان پایه منتقل شده است. دلیل این تغییر، چرخه پشتیبانی طولانی‌تر Ubuntu است، به طوری که نسخه .NET درون کانتینر قبل از توزیع لینوکس میزبان برنامه شما منقضی نشود. تفاوت‌های قابل توجهی بعید است، اما بهتر است احتیاط کنید. برای توضیح بیشتر، تست کانتینرهای خود را در محیط‌های CI/CD انجام دهید تا از سازگاری با ابزارهای جدید مطمئن شوید.

حذف محدودیت طول Uri هنگام ایجاد نمونه‌های جدید
این تغییر می‌تواند برای توسعه‌دهندگان مفید باشد، اما ممکن است مشکلات زمان اجرای بیشتری ایجاد کند. از .NET 10، هنگام ایجاد Uri با بیش از ۶۵,۰۰۰ کاراکتر، استثنای زمان اجرا پرتاب نمی‌شود:
new Uri($"https://host/{new string('a', 100_000)}")
اگرچه اکنون می‌توانید Uriهای بزرگ ایجاد کنید، سرور مقصد باید قادر به پذیرش این payloadهای بزرگ باشد؛ در غیر این صورت، انتظار استثنا داشته باشید. لطفاً از عقل سلیم و قضاوت استفاده کنید.

پارامترهای کلید X509Certificate و PublicKey می‌توانند null باشند
تغییر جزئی در رفتار کلاس X509Certificate ممکن است باعث استثناهای زمان اجرا شود که باید مراقب آن باشید. کلاس‌های X509Certificate، X509Certificate2 و PublicKey اطلاعات Subject Public Key Info را افشا می‌کنند. یکی از ویژگی‌های Subject Public Key Info، پارامترهای الگوریتم است. Subject Public Key Info الزامی برای درج پارامترهای الگوریتم ندارد. قبلاً، این به عنوان آرایه بایت خالی نشان داده می‌شد که ASN.1 معتبر نیست و منجر به استثنا می‌شد. اکنون، برای نشان دادن غیبت پارامترهای کلید، null برگردانده می‌شود و اعضای بازگشتی پارامترهای الگوریتم به عنوان nullable حاشیه‌نویسی شده‌اند.
هنگام کار با گواهی، به صورت دفاعی کد بنویسید و بررسی کنید که نتیجه null نباشد:
byte[] parameters = certificate.GetKeyAlgorithmParameters();
if (parameters == null)
{
    // مدیریت غیبت پارامترهای الگوریتم
}
این تغییر با استانداردهای ASN.1 سازگارتر است و می‌تواند در سناریوهای رمزنگاری پیشرفته مفید باشد.


مشاهده مطلب اصلی