نظرات مطالب
یکپارچه سازی سیستم اعتبارسنجی ASP.NET MVC با Kendo UI validator
مراجعه کنید به مطلب «اعتبار سنجی ورودی‌های کاربر در Kendo UI». در انتهای مطلب در مورد «اعتبارسنجی سفارشی در DataSource»  بحث شده‌است. Kendo UI Grid هم اطلاعات اعتبارسنجی فیلدهای خودش را از data source دریافت می‌کند و ... اصول طراحی اعتبارسنجی آن، هیچ تفاوتی با نکته‌ی عنوان شده ندارد (یک custom rule سفارشی را به نام remote، دقیقا مانند همین مثال می‌توانید اضافه کنید).
نظرات مطالب
ASP.NET MVC #10
برای نمونه اگر حروف ویژه‌ی سه رقم جدا کننده هزارها در عدد ارسالی وجود داشته باشد، عبارت دریافتی قابل تبدیل به عدد نیست و مقدار دریافتی صفر خواهد بود. راه حل آن نوشتن یک model binder سفارشی است که در انتهای بحث « سفارشی سازی عناصر صفحات پویای افزودن و ویرایش رکوردهای jqGrid در ASP.NET MVC»  مطرح شده‌است.
نظرات مطالب
اعتبارسنجی در Entity framework Code first قسمت اول

- کاری که می‌خوای، منطقا زیر سؤاله. هم قرار نال پذیر باشه. هم کاربر باید اجبارا پرش کنه! یعنی چی اینکار؟!

- در مورد ویژگی‌های اعتبار سنجی سفارشی و مدیریت کدهای سمت کلاینت اون‌ها مطلب در سایت موجوده:

طراحی ValidationAttribute دلخواه و هماهنگ سازی آن با ASP.NET MVC

MVC 13 قسمت اعتبارسنجی سفارشی

پاسخ به بازخورد‌های پروژه‌ها
Custom Membership
پیشنهاد می‌کنم اگر نیاز به تنظیم دسترسی در سطح اکشن رو دارید ، یک Attribute سفارشی بنویسید و اون رو بصورت سراسری به همه کنترلرها بدید.

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

در پروژه‌های ساده‌تر اگر دوست دارید همه چی رو کنترل کنین ، می‌تونید یک Role Provider سفارشی بنویسید، اگر نه می‌تونین از Identity بهره ببرید
پاسخ به بازخورد‌های پروژه‌ها
استفاده از progressBar در درون یک CustomCellTemplate
نه به صورت مستقیم.
 سورس آن در دسترس هست. در متد public void CellRendered کار نقاشی داخل یک سلول انجام می‌شود. اگر در سلول سفارشی خودتون برای مثال یک جدول قرار دادید و می‌خواهید در یکی از سلول‌های آن این نقاشی را اعمال کنید، باید خاصیت CellEvent آن‌را مقدار دهی کرده و سپس در public void CellLayout رخدادگردان آن درصد پیشرفت را نمایش دهید. یک مثال در مورد پیاده سازی CellEvent سفارشی.
پاسخ به بازخورد‌های پروژه‌ها
استفاده از فونت های مختلف در گزارش
بله مربوط به Header سفارشی است. ممنون برای Header سفارشی هم من رفتم کد زیر رو نوشتم درست شد
 var fontPath = AppPath.ApplicationPath + "\\Fonts\\BNAZANIN.TTF";
            //Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf";
        var baseFont = BaseFont.CreateFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        var tahomaFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.BLACK);
ولی اینجا دیگه نمی‌تونم دو فونت یعنی یک فونت برای فارسی و یک فونت برای انگلیسی تعریف کنم؟
نظرات نظرسنجی‌ها
آیا با وجود سی‌ام‌اس فروشگاهی قدرتمندی مثل nopCommerce یا SmartStore آیا منطقی است که ما دوباره خودمان از صفر کد بزنیم؟
(( با تجربه ای که در ecommerce‌های مختلف داشته ام (PHP و ASP.NET) در مقیاس‌های کوچک، متوسط ، بزرگ و خیلی بزرگ به شما پیشنهاد می‌کنم هر ابزاری را برای کاربرد مناسب انتخاب کنید. هیچ CMS همه کاره ای برای همه پروژه‌ها وجود ندارد.  ))

لطف میکنید از گزینه هایی که استفاده کردید نام ببرید؟برای مقاصد متفاوت کدام را استفاده نمودید یا اینکه بنظر شما کدامیک قابلیت سفارشی سازی بهتری دارد ؟
آیا میشود از بین CMS هایی که کار کردین قابلیت سفارشی شده رو طوری اعمال نمود تا به چیزی مثل دیجی کالا یا ebay  یا .. رسید؟
نظرات مطالب
بررسی قابلیت Endpoint Routing در ASP.NET Core
ارتقاء به ASP.NET Core 3.0: دریافت مقادیر Routing پس از فعالسازی Endpoint routing

تا پیش از معرفی Endpoint routing، اطلاعات مسیریابی جاری را می‌شد از طریق یکی از روش‌های زیر به دست آورد:
  // services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
    private readonly IActionContextAccessor _actionContext;

public MyClass(IActionContextAccessor actionContext)
    {
        _actionContext = actionContext;
    }

    public string GetData()
    {
        var routes = _actionContext.ActionContext.RouteData;
        var val = routes.Values["action"]?.ToString() as string;
        return val;
    }
در اینجا سرویس IActionContextAccessor امکان دسترسی به Context اکشن متد در حال اجرا را در قسمت‌های مختلف برنامه میسر می‌کرد و یا شبیه به آن در یک AuthorizationHandler سفارشی، context آن از نوع AuthorizationFilterContext بود که آن نیز دسترسی به اطلاعات context اکشن متد در حال اجرا را در اختیار برنامه قرار می‌داد:
protected override async Task HandleRequirementAsync(
   AuthorizationHandlerContext context,
   DynamicPermissionRequirement requirement)
{
    if (!(context.Resource is AuthorizationFilterContext mvcContext))
    {
      return;
    }

    var actionDescriptor = mvcContext.ActionDescriptor;
    actionDescriptor.RouteValues.TryGetValue("area", out var areaName);
    var area = string.IsNullOrWhiteSpace(areaName) ? string.Empty : areaName;
این روش‌ها دیگر در ASP.NET Core 3.0 کار نمی‌کنند. در اینجا پس از تزریق IHttpContextAccessor به سازنده‌ی کلاس مدنظر، می‌توان توسط متد الحاقی ()HttpContext.GetRouteData به اطلاعات مسیریابی دسترسی داشت:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;

namespace ASPNETCoreIdentitySample.Services.Identity
{
    public class DynamicPermissionsAuthorizationHandler : AuthorizationHandler<DynamicPermissionRequirement>
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

        public DynamicPermissionsAuthorizationHandler(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
        }

        protected override async Task HandleRequirementAsync(
             AuthorizationHandlerContext context,
             DynamicPermissionRequirement requirement)
        {
            var routeData = _httpContextAccessor.HttpContext.GetRouteData();

            var areaName = routeData?.Values["area"]?.ToString();
            var area = string.IsNullOrWhiteSpace(areaName) ? string.Empty : areaName;
بازخوردهای پروژه‌ها
مشکل در فوتر
با سلام و احترام
من از فوتر سفارشی استفاده کردم که مطلبی رو در هر صفحه نمایش داده شود
اما مشکل به این صورت است که در صفحه اول فوتر و جدول اصلی روی هم قرار میگیره اما در بقیه صفحات این مشکل وجود نداره آیا در استفاده من ایرادی وجود داره؟

        public void PageFinished(PdfWriter writer, Document document, IList<SummaryCellData> columnCellsSummaryData)
        {
            var pageSize = document.PageSize;
            var text = "صفحه " + writer.PageNumber + " از ";
            var textLen = _font.BaseFont.GetWidthPoint(text, _font.Size) + 17;
            var positionX = pageSize.Right - 10;
            var align = _direction == PdfRunDirection.RightToLeft ? Element.ALIGN_RIGHT : Element.ALIGN_LEFT;
            ColumnText.ShowTextAligned(
                canvas: _pdfContentByte,
                alignment: align,
                phrase: ReportMethod.SetFont(text, 20),
                x: positionX,
                y: pageSize.GetBottom(4),
                rotation: 0,
                runDirection: (int)_direction,
                arabicOptions: 0);
            var x = _direction == PdfRunDirection.RightToLeft ? positionX - textLen : positionX + textLen;
            _pdfContentByte.AddTemplate(_template, x, pageSize.GetBottom(4));
            //--------------------------------------
            if (_Info != null)
            {
                var table = new PdfGrid(1) { RunDirection = (int)_direction, WidthPercentage = 100 };

                string[] msgField = { "مدیر گروه", _Info.Where(sp => sp.ID == _MemberID).FirstOrDefault().InstKindName, _Info.Where(sp => sp.ID == 0).FirstOrDefault().InstKindName, "امور مالی", "معاون پشتیبانی" };
                string[] dataField = { "", _Info.Where(sp => sp.ID == _MemberID).FirstOrDefault().MasterName, _Info.Where(sp => sp.ID == 0).FirstOrDefault().MasterName, "", _Info.Where(sp => sp.ID == 1).FirstOrDefault().MasterName };
                var infoTable = new PdfGrid(msgField.Length) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, WidthPercentage = 100 };
                foreach (var item in msgField)
                {
                    infoTable.AddCell(ReportMethod.SetCell(item, PdfPCell.NO_BORDER, 1, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, true, 20));
                }
                foreach (var item in dataField)
                {
                    infoTable.AddCell(ReportMethod.SetCell(item, PdfPCell.NO_BORDER, 1, PdfPCell.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE, true, 20));
                }

                table.AddCell(infoTable);
                table.SetTotalWidth(new[] { pageSize.Width - document.LeftMargin - document.RightMargin });
                table.WriteSelectedRows(
                        rowStart: 0,
                        rowEnd: -1,
                        xPos: document.LeftMargin,
                        yPos: document.BottomMargin - 10,
                        canvas: writer.DirectContent);

            }
        }