پاسخ به بازخورد‌های پروژه‌ها
مشکل در نمایش حروف انگلیسی HtmlHeader
- یک مثال جدید در این مورد اضافه کردم: (^). این مثال با آخرین نگارش موجود در SVN سازگار است.
- و بله. فونت Iranian Sans حاوی حروف انگلیسی نیست. در حالت Html هم استفاده از fallback فونت انگلیسی درنظر گرفته نشده (در خود iTextSharp مساله وجود دارد).
راه حل این است که فونت مورد نظر را صریحا در اینجا ذکر کنید (و این فونت باید در قسمت فونت‌های پیش فرض تعریف شده باشد). مثلا:

<span style='font-family:tahoma;'>Department</span>
مطالب
پلاگین DataTables کتابخانه jQuery - قسمت سوم
در این قسمت اطلاعات را به صورت ajax از یک فایل متنی می‌خوانیم و آنها را در جدول قرار می‌دهیم. سپس به سفارشی کردن بعضی از قسمت‌های DataTables خواهیم پرداخت.

دریافت اطلاعات به صورت ajax از یک فایل متنی

فرض کنید که اطلاعات در یک فایل txt به صورت اشیاء جاوا اسکریپتی ذخیره شده اند، و این فایل بر روی سرور قرار دارد. می‌خواهیم از این فایل به عنوان منبع داده استفاده کرده و اطلاعات درون آن را به صورت ajax دریافت کرده و در یک جدول html تزریق کنیم. خوشبختانه با استفاده از امکاناتی که این پلاگین تهیه کرده است این کار به سادگی امکان پذیر است.

همان طور که در اینجا بیان شده است ، فرض کنید که جدولی داشته باشیم و بخواهیم اطلاعات راجع به مرورگرهای مختلف را در آن نمایش دهیم. قصد داریم این جدول شامل قسمتهای header و footer و نیز body باشد، بدین صورت:
<table id="browsers-grid">
    <thead>
       <tr>
          <th width="20%">موتور رندرگیری</th>
          <th width="25%">مرورگر</th>
          <th width="25%">پلتفرم (ها)</th>
          <th width="15%">نسخه موتور</th>
          <th width="15%">نمره css</th>
       </tr>
    </thead>

    <tbody>

    </tbody> 

    <tfoot>
       <tr>
          <th>موتور رندرگیری</th>
          <th>مرورگر</th>
           <th>پلتفرم (ها)</th>
          <th>نسخه موتور</th>
          <th>نمره css</th>
       </tr>
    </tfoot>
</table>
برای هر ستون از این جدول عرضی در نظر گرفته شده است. اگر این کار انجام نشود به صورت خودکار به تمام ستونها عرض داده می‌شود.

داده هایی که باید در بدنه جدول قرار بگیرند، در یک فایل متنی روی سرور قرار دارند. محتویات این فایل چیزی شبیه زیر است:
{
   "aaData": [
      {"engine":"Trident", "browser":"Internet Explorer 4.0", "platform":"Win95+", "version":"4", "grade":"X"},
      {"engine":"Trident", "browser":"Internet Explorer 5.0", "platform":"Win95+", "version":"5", "grade":"C"},
      {"engine":"Trident", "browser":"Internet Explorer 5.5", "platform":"Win95+", "version":"5.5", "grade":"A"}
   ]
}
همان طور که مشاهده می‌کنید فرمت ذخیره داده‌ها در این فایل به صورت json یا اشیاء جاوا اسکریپتی است. این اشیاء باید به خصوصیت aaData نسبت داده شوند که در قسمت قبل راجع به آن توضیح دادیم. تعداد این اشیاء 57 تا بود که برای سادگی بیشتر 3 تا از آنها را اینجا ذکر کردیم.

اسکریپتی که داده‌ها را از فایل متنی خوانده و آنها را در جدول قرار می‌دهد هم بدین صورت خواهد بود:
$(document).ready(function () {
        $('#browsers-grid').dataTable({
            "sAjaxSource": "datasource/objects.txt",
            "bProcessing": true,
            "aoColumns": [
                { "mDataProp": "engine" },
                { "mDataProp": "browser" },
                { "mDataProp": "platform" },
                { "mDataProp": "version" },
                { "mDataProp": "grade" }
            ]
    });
});
شرح کد:
sAjaxSource : رشته
نوع داده ای که قبول می‌کند رشته ای و بیان کننده آدرسی است که داده‌ها باید از آنجا دریافت شوند. در اینجا داده‌ها در فایل متنی objects.txt در پوشه datasource قرار دارند.

bProcessing : بولین
نوع داده‌های قابل قبول این خصوصیت true یا false هست و بیان کننده این است که یک پیغام loading تا زمانی که داده‌ها دریافت شوند و در جدول قرار بگیرند نمایش داده شوند یا خیر.


تنظیم کردن گزینه‌های اضافی دیگر

sAjaxDataProp : رشته
همان طور که گفتیم در فایل متنی که حاوی اشیاء json بود ، این اشیاء را به متغیری به اسم aaData منتسب کردیم. این نام را می‌توان تغییر داد مثلا فرض کنید در فایل متنی داده‌ها به متغیری به اسم data منتسب شده اند:
{
   "data": [
      {"engine":"Trident", "browser":"Internet Explorer 4.0", "platform":"Win95+", "version":"4", "grade":"X"},
      {"engine":"Trident", "browser":"Internet Explorer 5.0", "platform":"Win95+", "version":"5", "grade":"C"},
      {"engine":"Trident", "browser":"Internet Explorer 5.5", "platform":"Win95+", "version":"5.5", "grade":"A"}
   ]
}
در این صورت باید خصوصیت sAjaxDataProp را به همان نامی که در فایل متنی مشخص کرده اید مقداردهی کنید، در غیر این صورت داده‌های جدول هیچ گاه بارگذاری نخواهند شد. بدین صورت:
"sAjaxDataProp": "data"
یا اگر داده‌ها را بدین صورت در فایل متنی ذخیره کرده اید:
{ "data": { "inner": [...] } }
آنگاه خصوصیت sAjaxDataProp بدین صورت مقداردهی خواهد شد:
"sAjaxDataProp": "data.inner"

sPaginationType: رشته
نحوه صفحه بندی و حرکت بین صفحات مختلف را بیان می‌کند. اگر با two_buttonمقدار دهی شود (مقدار پیش فرض) حرکت بین صفحات مختلف به وسیله دکمه‌های Next و Previous امکان پذیر خواهد بود. اگر با full_numbersمقدار دهی شود حرکت بین صفحات با دکمه‌های Next و Previous ، و همچنین دکمه‌های First و Last و نیز شماره صفحه فعلی و دو صفحه بعدی و دو صفحه قبلی قابل انجام است.

شکل الف) صفحه بندی به صورت full_numbers

bLengthChange: بولین
بیان می‌کند کاربر بتواند اندازه صفحه را تغییر دهید یا نه. به صورت پیش فرض این گزینه true است. اگر آن به false مقدار دهی شود لیست بازشونده مربوط به اندازه صفحه مخفی خواهد شد.

aLengthMenu  :  آرایه یک بعدی یا دو بعدی
به صورت پیش فرض در لیست باز شونده مربوط به تعداد رکوردهای قابل نمایش در هر صفحه اعداد 10 ، 25 ، 50 ، و 100 قرار دارند.

شکل ب ) لیست بازشونده شامل اندازه‌های صفحه

در صورتی که بخواهیم این گزینه‌ها را تغییر دهیم باید خصوصیت aLengthMenu را مقدار دهی کنیم. اگر مقداری که به این خصوصیت می‌دهیم یک آرایه یک بعدی باشد، مثلا

"aLengthMenu": [25, 50, 100, -1],
نتیجه یک لیست باز شوند است که دارای چهار عنصر است که value و text آنها یکی است. (نکته: چهارمین عنصر از لیست بالا دارای مقدار 1- خواهد بود که با انتخاب این گزینه تمام رکوردها نمایش می‌یابند). اما اگر می‌خواهیم که text و value این عناصر با هم فرق کند از یک آرایه دو بعدی استفاده خواهیم کرد، مثلا:

"aLengthMenu": [[25, 50, 100, -1], ["همه", "صد", "پنجاه", "بیست و پنج"]],

iDisplayLength
: عدد صحیح
تعداد رکوردهای قابل نمایش در هر صفحه هنگامی که داده‌ها در جدول ریخته می‌شوند را معین می‌کند. می‌توانید این را مقداری بدهید که در خصوصیت aLengthMenu ذکر نشده است، مثلا 28 تا.


sDom : رشته
پلاگین DataTables به صورت پیش فرض لیست بازشونده اندازه صفحه و کادر متن مربوط به جستجو را در بالای جدول داده‌ها اضافه می‌کند، و نیز اطلاعات دیگر و همچنین امکانات مربوط به صفحه بندی را به قسمت پایین جدول اضافه می‌کند. شما می‌توانید موقعیت این عناصر را با استفاده از پارامتر sDom تغییر دهید.

نحو (syntax) مقداری که پارامتر sDom قبول می‌کند مقداری عجیب و غریب است، مثلا:

'<"top"iflp<"clear">>rt<"bottom"iflp<"clear">>'

این خط بیان می‌کند که در قسمت بالای جدول یک تگ div با کلاس top قرار بگیرد. در این تگ قسمت اطلاعات (یعنی Showing x to xx from xxx entries) (با حرف i) ، کادر جستجو (با حرف f) ، لیست بازشونده مربوط به اندازه صفحه (با حرف l) ، و نیز قسمت صفحه بندی (با حرف p)قرار خواهند گرفت. در انتهای تگ div با کلاس top، یک تگ div با کلاس clear قرار خواهد گرفت. بعد قسمت مربوط به پیغام loading (با حرف r) و بعد با حرف t جدول حاوی داده‌ها قرار می‌گیرد. در نهایت یک تگ div با کلاس bottom قرار می‌گیرد و با حرفهای i ، و f ، و l و p درون آن قسمتهای اطلاعات ، کادرجستجو، لیست بازشونده اندازه صفحه و نیز قسمت صفحه بندی قرار خواهد گرفت و در نهایت یک تگ div با کلاس clear قرار خواهد گرفت.

حرفهایی که در sDom معنی خاصی می‌دهند :
  • l سر حرف Length Changing برای لیست بازشونده مربوط به اندازه صفحه
  • f سر حرف Filtering input برای قسمت کادر جستجو
  • t سرحرف table برای جدول حاوی داده ها
  • i سر حرف information برای قسمت Showing x to xx from xxx entries
  • p سر حرف pagination برای قسمت صفحه بندی
  • r حرف دوم pRocessing برای قسمت پیغام قبل از بار کردن داده‌های جدول (قسمت loading)
  • H و F که مربوط به theme‌های jQuery UI می‌شوند که بعدا درباره آنها توضیح داده می‌شود.

همچنین بین علامت‌های کوچکتر (>) و بزرگتر (<) یعنی اگر چیزی بیاید در یک تگ div قرار خواهد گرفت. اگر بخواهیم div ی بسازیم و به آن کلاس بدهیم از نحو زیر استفاده خواهیم کرد:

'<"class" and '>'
و اگر بخواهیم یک تگ div با یک id مشخص بسازیم از نحو زیر استفاده خواهیم کرد:
'<"#id" and '>'
در نهایت جدولی مثل جدول زیر تولید خواهد شد:

شکل ج) جدول نهایی تولید شده توسط DataTables

کدهای نهایی این مثال را از DataTables-DoteNetTips-Tutorial-03.zip دریافت کنید.
نظرات مطالب
غنی سازی کامپایلر C# 9.0 با افزونه‌ها
یک نکته‌ی تکمیلی: ارتقاء به NET 7.0.12. و دریافت خطای CA1852

اگر نکات این مطلب را پیاده سازی کرده و برای مثال TreatWarningsAsErrors را فعال کرده باشید، با ارتقاء به NET 7.0.102. حتی در مورد فایل Program.cs نیز خطای زیر را دریافت خواهید کرد:
CA1852:  Type can be sealed because it has no subtypes in its containing assembly and is not externally visible
عموما از هر نگارشی به نگارش دیگر، تعداد آنالایزرهای توکار دات نت بیشتر می‌شوند. یک چنین موردی در نگارش ابتدایی دات نت 7 وجود نداشت، اما الان قابل مشاهده است. در جهت مواجه شدن با آن یا می‌توان کلاس عنوان شده را با واژه‌ی کلیدی sealed مزین کرد و یا فقط کافی است فایل editorconfig. را باز کرده و یک سطر زیر را به آن اضافه کنید:
dotnet_diagnostic.CA1852.severity = suggestion
به این صورت میزان شدت گزارش یاد شده، صرفا به یک توصیه تقلیل پیدا می‌کند و مانع build برنامه نخواهد شد؛ هرچند در IDE هنوز به صورت یک هشدار آبی رنگ قابل مشاهده‌است.
نظرات مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 5 - فعال سازی صفحات مخصوص توسعه دهنده‌ها
ارتقاء به ASP.NET Core 3.0

در کلاس آغازین برنامه‌های وب نگارش 3، بجای متد
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
اینبار متد زیر با معرفی IWebHostEnvironment مشاهده می‌شود (چون این نوع قبلی در دو اسمبلی Microsoft.Extensions.Hosting و Microsoft.AspNetCore.Hosting تعریف شده بوده، جهت رفع ابهام مجبور به این تغییرات شده‌اند):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
و برای اینکه متدهای الحاقی مانند ()env.IsDevelopment  شناسایی شوند، نیاز به افزودن فضای نام زیر می‌باشد:
using Microsoft.Extensions.Hosting;
البته امضای قبلی، هنوز هم در نگارش 3 کار می‌کند؛ اما در نگارش‌های بعدی حذف خواهد شد.
به صورت خلاصه هرجائی در برنامه‌ی خود IHostingEnvironment دارید، باید به IWebHostEnvironment تبدیل شود. همچنین اگر از سرویس IApplicationLifetime در جائی استفاده کرده‌اید، باید به IHostApplicationLifetime تبدیل گردد.
نظرات مطالب
ارتقاء به ASP.NET Core 2.0 - معرفی بسته‌ی Microsoft.AspNetCore.All
ارتقاء به ASP.NET Core 3.0 و سرنوشت metapackageهای Microsoft.AspNetCore

پس از نصب SDK جدید، اگر دستور dotnet new mvc را صادر کنید، فایل csproj تولید شده‌ی آن تنها دارای TargetFramework ای معادل netcoreapp3.0 است و نه هیچ مورد دیگری:
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
  </ItemGroup>
</Project>
بنابراین برای ارتقاء پروژه‌های قبلی به نگارش 3 آن:
- ابتدا TargetFramework را به netcoreapp3.0 تنظیم کنید.
- سپس تمام PackageReferenceهایی را که به بسته‌های Microsoft.AspNetCore.All و یا Microsoft.AspNetCore.App اشاره می‌کنند، حذف کنید.
- ارجاع به بسته‌ی Microsoft.AspNetCore.Razor.Design را نیز حذف کنید.
- اگر پیشتر خاصیت AspNetCoreHostingModel را به حالت درون پروسه‌ای تنظیم کرده‌اید، آن‌را حذف کنید؛ چون حالت پیش‌فرض نگارش 3 است.
- حذف شدن JSON.NET را مدنظر داشته باشید.
- تغییرات حالت ثبت سرویس‌های MVC و Razor Pages و Web API را مدنظر داشته باشید.
- مسیریابی آن نیز Endpoint routing شده‌است.
- نقطه‌ی آغازین آن نیز بازنویسی شده‌است.
نظرات مطالب
ارتقاء به ASP.NET Core 2.0 - معرفی بسته‌ی Microsoft.AspNetCore.All
امکان اجرای درون پروسه‌ای در نگارش 2.2 میسر هست و دقیقا جزئی از بسته‌ی هاستینگ آن است (لینک مطرح شده‌ی در نظر فوق قدیمی است). فقط در این حالت ممکن است برنامه مسیرهای فایل‌های مشخص شده‌ی در آن را پیدا نکند. باید با دستور dotnet ./proj.dll برنامه را اجرا کنید (و یا یکی از روش‌های مطرح شده‌ی در مطلب «بررسی خطاهای ممکن در حین راه اندازی اولیه برنامه‌های ASP.NET Core در IIS») و دقیقا مشاهده کنید که مشکل از کجاست. چند مثال از این نوع:
هر دو مورد به این اشاره می‌کنند که در نگارش فعلی این ماژول درون پروسه‌ای، متد Directory.GetCurrentDirectory بجای اینکه مسیر برنامه را باز گرداند، مسیر C:\windows\system32\inetsrv یا همان پروسه‌ی IIS را بر می‌گرداند و باید به این موضوع دقت داشت.  
نظرات مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 22 - توزیع برنامه توسط IIS
بهبود کارآیی برنامه‌های ASP.NET Core 2.1 هاست شده‌ی در IIS

تا پیش از نگارش 2.1، تمام درخواست‌های رسیده‌ی به IIS توسط یک پروکسی معکوس به نام ASP.NET Core Module به Kestrel ارسال می‌شدند:


در نگارش 2.1، می‌توان کل برنامه را داخل IIS worker process یا همان w3wp.exe هاست کرد تا تاثیر منفی این پروکسی معکوس حذف شود. با بررسی‌های انجام شده، این روش بهبود کارآیی بیش از 4 برابری را به همراه دارد؛ نسبت به حالت out-of-process فعلی (تصویر فوق).
برای فعالسازی آن یا فایل web.config را به صورت ذیل جهت تعیین hostingModel ویرایش کنید:
 <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" hostingModel="inprocess" />
و یا فایل csproj برنامه را به صورت زیر تنظیم نمائید:
 <PropertyGroup>
    <AspNetCoreModuleHostingModel>inprocess</AspNetCoreModuleHostingModel>
</PropertyGroup>
نظرات مطالب
استفاده از pjax بجای ajax در ASP.NET MVC
- المان‌هایی که به صورت پویا به صفحه اضافه می‌شوند، تحت کنترل مجدد jQuery نخواهند بود، مگر اینکه از متدهای live (منسوخ شده) و یا on استفاده شود. مطابق مستندات این کتابخانه (انتهای صفحه)، متد on به صورت پیش فرض، برای کارکرد مجدد pjax، اعمال می‌شود. بنابراین فقط باید بررسی کنید که آیا نگارش jQuery مورد استفاده، از متد on پشتیبانی می‌کند یا خیر (از آخرین نگارش آن استفاده کنید).
- همچنین تمام کدهای سایر قسمت‌های برنامه هم مانند دکمه امتیازدهی که اشاره شد، باید تغییر کرده و از متد on استفاده کنند. مثلا اگر click دارند، باید بشوند on click.
//The new api
$(document).pjax('a[withpjax]', '#pjax-container')

//Which is roughly the same as
$(document).on('click', 'a[withpjax]', function(event) {
  $.pjax.click(event, '#pjaxContainer')
})
نظرات مطالب
الگوی استراتژی - Strategy Pattern
تفاوت مهمی نداره؛ فقط اینترفیس ورژن پذیر نیست. یعنی اگر در این بین متدی رو به تعاریف اینترفیس خودتون اضافه کردید، تمام استفاده کننده‌ها مجبور هستند اون رو پیاده سازی کنند. اما کلاس Abstract می‌تونه شامل یک پیاده سازی پیش فرض متد خاصی هم باشه و به همین جهت ورژن پذیری بهتری داره.
بنابراین کلاس Abstact یک اینترفیس است که می‌تواند پیاده سازی هم داشته باشد.
همین مساله خاص نگارش پذیری، در طراحی ASP.NET MVC به کار گرفته شده: (^ )
برای من نوعی شاید این مساله اهمیتی نداشته باشه. اگر من قرارداد اینترفیس کتابخانه خودم را تغییر دادم، بالاخره شما با یک حداقل نق زدن مجبور به به روز رسانی کار خودتان خواهید شد. اما اگر مایکروسافت چنین کاری را انجام دهد، هزاران نفر شروع خواهند کرد به بد گفتن از نحوه مدیریت پروژه تیم‌های مایکروسافت و اینکه چرا پروژه جدید آن‌ها با یک نگارش جدید MVC کامپایل نمی‌شود. بنابراین انتخاب بین این دو بستگی دارد به تعداد کاربر پروژه شما و استراتژی ورژن پذیری قرار دادهای کتابخانه‌ای که ارائه می‌دهید.
نظرات مطالب
نصب Mono Develop 4.x در Ubuntu
یک نکته تکمیلی در مورد نصب از روی PPA
اگر یک برنامه جدید را در monodevelop شروع کردید و به خطای کامپایل ذیل برخوردید:
Error: A dependency of a referenced assembly may be missing, or you may be referencing an 
assembly created with a newer CLR version. See the compilation output for more details. (Test1)
به این معنا است که mono تنظیم شده در مسیرهای لینوکس، به آخرین نگارش تنظیم نیست. برای رفع این مشکل دستورات ذیل را صادر و بعد monodevelop را اجرا کنید:
export PATH=/opt/mono-3/bin:$PATH
export PKG_CONFIG_PATH=/opt/mono-3/lib/pkgconfig:$PKG_CONFIG_PATH
mono -V
بسته PPA، نگارش 3.2.1 را در مسیر opt/mono-3 نصب می‌کند.