پیشنهادها
C# 7 - Ref Returns and Ref Locals
بازخوردهای دوره
پیاده سازی دکمه «بیشتر» یا «اسکرول نامحدود» به کمک jQuery در ASP.NET MVC
- شاید خطایی وجود دارد که باید بررسی کنید: نحوه استفاده از افزونه Firebug برای دیباگ برنامه‌های ASP.NET مبتنی بر jQuery 
- در اینجا محدودیتی در مورد تعداد پارامترها ندارید. برای مثال لینک قسمت مطالب سایت جاری به این صورت است:
https://www.dntips.ir/postsarchive#/page/1/date/asc
در اینجا پارامترهای شماره صفحه، فیلد و صعودی و نزولی بودن آن ذکر شدند. پارامترهای دیگری را هم اگر علاقمند بودید (مانند زبان یا هر مورد دیگری) اضافه کنید. فایل jquery.InfiniteScroll.js پیوست شده یک مثال در این مورد است (نحوه تنظیم و دریافت پارامترها و نحوه‌ی واکنش به پارامترهای دریافتی). مستندات رسمی آن‌را هم فراموش نکنید.
نظرات مطالب
ارسال ایمیل در ASP.NET Core
جهت اطلاع
مایکروسافت به صورت رسمی SmtpClient را منسوخ شده اعلام کرده و توصیه می‌کند که از MailKit استفاده کنید:
[System.Obsolete("SmtpClient and its network of types are poorly designed, we strongly recommend you use https://github.com/jstedfast/MailKit and https://github.com/jstedfast/MimeKit instead")]
public class SmtpClient : IDisposable
ماخذ (مستندات دات نت 4.7)
نظرات مطالب
تغییرات بوجود آمده در Bundling and Minification -MVC4
اینطور نیست. مطابق مستندات رسمی آن ، HTTP Expires Header به مدت یکسال بر روی منابع تولیدی تنظیم می‌شود (و مرورگر مرتبا درخواست دریافت این منابع را نمی‌دهد). اینجا است که نیاز به غیرمعتبر کردن کش نیز وجود خواهد داشت. بنابراین در انتهای لینک تولیدی اگر دقت کرده باشید css?v=something وجود دارد. این v به معنای نگارش است. اگر این نگارش که به صورت خودکار بر اساس هش فایل‌ها تولید می‌شود تغییر کند، مرورگر کش خود را به روز خواهد کرد.
ضمن اینکه در اینجا قرار نیست فایلی یا فایل‌هایی با همان نام‌های اصلی ارسال شوند. به این دلیل که هدف اصلی این کار bundling، کم کردن تعداد درخواست‌ها به سرور نیز هست. برای مثال اگر سایت شما از 8 فایل اسکریپت استفاده می‌کند، در اینجا تبدیل به یک فایل خواهد شد که سبب کم شدن تعداد درخواست‌ها و سریع‌تر شدن نمایش صفحات می‌شود.
مطالب
امکان استفاده‌ی از قیود مسیریابی سفارشی ASP.NET Core در Blazor SSR برای رمزگشایی خودکار پارامترهای دریافتی

در Blazor می‌توان مسیریابی‌های پارامتری را به صورت زیر نیز تعریف کرد:

@page "/post/edit/{EditId:int}"

که در اینجا EditId، یک پارامتر مسیریابی از نوع int تعریف شده و به صورت زیر در کدهای صفحه‌ی مرتبط، قابل دسترسی است:

[Parameter] public int? EditId { set; get; }

int تعریف شده‌ی در این مسیریابی، یک routing constraint و یا یک قید مسیریابی محسوب می‌شود و استفاده‌ی از آن، چنین مزایایی را به همراه دارد:

- در این حالت فقط EditId های عددی پردازش می‌شوند و اگر رشته‌ای دریافت شود، کاربر با خروجی از نوع 404 و یا «یافت نشد»، مواجه خواهد شد.

- امکان اعتبارسنجی مقادیر دریافتی، پیش از ارسال آن‌ها به صفحه و پردازش صفحه.

قیود پیش‌فرض تعریف شده‌ی در Blazor

اگر به مستندات مسیریابی Blazor مراجعه کنیم، به‌نظر فقط این موارد را می‌توان به‌عنوان قیود پارامترهای مسیریابی تعریف کرد:

bool, datetime, decimal, double, float, guid, int, long, nonfile 

و ... توضیحاتی در مورد اینکه آیا امکان بسط آن‌ها وجود دارند یا خیر، فعلا در مستندات رسمی آن، ذکر نشده‌اند.

در Blazor 8x می‌توان از قیود مسیریابی سفارشی ASP.NET Core نیز استفاده کرد!

ASP.NET Core سمت سرور، به همراه امکان سفارشی سازی قیودمسیریابی خود نیز هست که آن‌را می‌توان به کمک اینترفیسIRouteConstraint پیاده سازی کرد:

namespace Microsoft.AspNetCore.Routing  
{  
    public interface IRouteConstraint  
    {  
        bool Match(  
            HttpContext httpContext,  
            IRouter route,  
            string routeKey,  
            RouteValueDictionary values,  
            RouteDirection routeDirection);  
    }  
} 

جالب اینجا است که می‌توان این نمونه‌های سفارشی را حداقل در نگارش جدید Blazor 8x SSR نیز استفاده کرد؛ هرچند در مستندات رسمی Blazor هنوز به آن‌ اشاره‌ای نشده‌است.

در امضای متد Match فوق، دو پارامتر routeKey و values آن بیش از مابقی مهم هستند:

- routeKey مشخص می‌کند که الان کدام پارامتر مسیریابی (مانند EditId در این مطلب) در حال پردازش است.

- values، یک دیکشنری است که کلید هر عضو آن، پارامتر مسیریابی و مقدار آن، مقدار دریافتی از URL جاری است.

- اگر این متد مقدار true را برگرداند، یعنی مسیریابی وارد شده‌ی به آن، با موفقیت پردازش و اعتبارسنجی شده و می‌توان صفحه‌ی مرتبط را نمایش داد؛ در غیراینصورت، کاربر پیام یافت نشدن آن صفحه و مسیر درخواستی را مشاهده می‌کند.

پیاده سازی یک قید سفارشی رمزگشایی پارامترهای مسیریابی

فرض کنید قصد ندارید که پارامترهای مسیریابی ویرایش رکوردهای خاصی را دقیقا بر اساس Id متناظر عددی آن‌ها در بانک اطلاعاتی، نمایش دهید؛ برای مثال نمی‌خواهید دقیقا آدرس post/edit/1 را به کاربر نمایش دهید؛ چون نمایش این اعداد عموما ساده و ترتیبی، حدس زدن آن‌ها را ساده‌ کرده و ممکن است در آینده مشکلات امنیتی را به همراه داشته باشد.

می‌خواهیم از آدرس‌های متداول و ساده‌ی عددی زیر:

@page "/post/edit/{EditId:int}"

به آدرس رمزنگاری شده‌ی زیر برسیم:

@page "/post/edit/{EditId:encrypt}"

اگر به این آدرس جدید دقت کنید، در اینجا از نام قید جدیدی به نام encrypt استفاده شده‌است که جزو قیود پیش‌فرض سیستم مسیریابی Blazor نیست. روش تعریف آن به صورت زیر است:

using System.Globalization;
using DNTCommon.Web.Core;

namespace Blazor8xSsrComponents.Utils;

public class EncryptedRouteConstraint(IProtectionProviderService protectionProvider) : IRouteConstraint
{
    public const string Name = "encrypt";

    public bool Match(HttpContext? httpContext,
        IRouter? route,
        string routeKey,
        RouteValueDictionary values,
        RouteDirection routeDirection)
    {
        ArgumentNullException.ThrowIfNull(routeKey);
        ArgumentNullException.ThrowIfNull(values);

        if (!values.TryGetValue(routeKey, out var routeValue))
        {
            return false;
        }

        var valueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture);
        values[routeKey] = string.IsNullOrEmpty(valueString) ? null : protectionProvider.Decrypt(valueString);

        return true;
    }
}

توضیحات:

- در قیود سفارشی می‌توان سرویس‌ها را به سازنده‌ی کلاس تزریق کرد و برای مثال از سرویس IProtectionProviderService که در کتابخانه‌ی DNTCommon.Web.Core تعریف شده، برای رمزگشایی اطلاعات رسیده، استفاده کرده‌ایم.

- یک نام را هم برای آن درنظر گرفته‌ایم که از این نام در فایل Program.cs به صورت زیر استفاده می‌شود:

builder.Services.Configure<RouteOptions>(opt =>
{
    opt.ConstraintMap.Add(EncryptedRouteConstraint.Name, typeof(EncryptedRouteConstraint));
});

یعنی زمانیکه سیستم مسیریابی به قید جدیدی به نام encrypt می‌رسد:

@page "/post/edit/{EditId:encrypt}"

آن‌را در لیست ConstraintMap ای که به نحو فوق به سیستم معرفی شده، جستجو می‌کند. اگر این نام یافت شد، سپس کلاس EncryptedRouteConstraint متناظر را نمونه سازی کرده و در جهت پردازش مسیر رسیده، مورد استفاده قرار می‌دهد.

- در کلاس EncryptedRouteConstraint و متد Match آن، مقدار رشته‌ای EditId دریافت شده‌ی از طریق آدرس جاری درخواستی، رمزگشایی شده و بجای مقدار فعلی رمزنگاری شده‌ی آن درج می‌شود. همین اندازه برای مقدار دهی خودکار پارامتر EditId ذیل در صفحات مرتبط، کفایت می‌کند:

[Parameter] public string? EditId { set; get; }

یعنی دیگر نیازی نیست تا در صفحات مرتبط، کار رمزگشایی EditId، به صورت دستی انجام شود.

نظرات اشتراک‌ها
مسابقه طراحی نرم افزار آموزشی
بله ، موقع ثبت نام کشور ایران هم وجود داره.احتمالا روند کلی مسابقه طوری هست که از مستندات برنامه نویسها محافظت میشه، در ثانی دنیا رو به رشد و تکنولوژی هست حتی مهمترین تراکنش‌های زندگی اشخاص که تراکنش‌های مالی هست الانه به صورت دیجیتال داره انجام میشه، و نیازی نیست هزینه زمان و جابجایی پرداخت کنیم پس بهتره برای کودکانمان هم از روش دیجیتال برای اموزش استفاده کنیم،خصوصا در این کشورها که به قول شما امکانات بهداشتی و رفاهیشون در حد صفر هست.
 مطمین باشید این روش نه تنها برای این کودکان بلکه برای همه کودکان در همه جای دنیا و حتی برای افراد مسن که سواد ندارند سودمند خواهد بود.