مطالب
گروه بندی اطلاعات در jqGrid
فرض کنید لیستی از مطالب را به فرمت ذیل در اختیار داریم:
namespace jqGrid10.Models
{
    public class Post
    {
        public int Id { set; get; }
        public string Title { set; get; }
        public string CategoryName { set; get; }
        public int NumberOfViews { set; get; }
    }
}
می‌خواهیم آن‌ها را با شرایط ذیل گروه بندی کنیم:
- گروه بندی بر روی ستون CategoryName انجام شود.
- ستونی که بر روی آن گروه بندی انجام می‌شود، نمایش داده نشود.
- در ابتدای نمایش گروه‌ها، تمام آن‌ها به صورت جمع شده و Collapsed نمایش داده شوند.
- پس از نمایش گروه‌ها، اولین گروه به صورت خودکار باز شود.
- تعداد ردیف هر گروه به عنوان گروه اضافه شود.
- جمع کل ستون تعداد بار مشاهدات هر گروه قابل محاسبه شود.
- جمع کل هر گروه در زمانیکه هر گروه نیز بسته‌است نمایش داده شود.
- رنگ ردیف جمع کل قابل تنظیم باشد.



فعال سازی گروه بندی در jqGrid

فعال سازی گروه بندی در jqGrid به سادگی افزودن تعاریف ذیل است:
            $('#list').jqGrid({
                caption: "آزمایش دهم",
                //...
                grouping: true,
                groupingView: {
                    groupField: ['CategoryName'],
                    groupOrder: ['asc'],
                    groupText : ['<b>{0} - {1} ردیف</b>'],
                    groupDataSorted: true,
                    groupColumnShow: false,
                    groupCollapse: true,
                    groupSummary: [true],
                    showSummaryOnHide: true
                }
            });
grouping: true سبب می‌شود تا گروه بندی فعال شود. سپس نیاز است ستون یا ستون‌هایی را که قرار است بر روی آن‌ها گروه بندی صورت گیرد، معرفی کنیم. اینکار توسط خواص شیء groupingView انجام می‌شوند.
groupField بیانگر آرایه‌ای از ستون‌هایی است که قرار است بر روی آن‌ها گروه بندی صورت گیرد.
groupOrder آرایه‌ای اختیاری از مقادیر asc یا desc است که متناظر هستند با نحوه‌ی مرتب سازی پیش فرض ستون‌های معرفی شده در آرایه groupField.
groupText آرایه‌ای اختیاری از عناوین گروه بندی‌های انجام شده‌است. اگر ذکر شود، {0} آن با نام گروه و {1} آن با تعداد عناصر گروه جایگزین می‌شود.
تنظیم groupDataSorted سبب خواهد شد تا نام ستونی که بر روی آن گروه بندی صورت می‌گیرد، به سرور ارسال شود (توسط پارامتر sidx). به این ترتیب در سمت سرور می‌توان اطلاعات را به صورت پویا مرتب سازی کرده و بازگشت داد.
با تنظیم groupColumnShow به false سبب خواهیم شد تا ستون‌های معرفی شده در قسمت groupField نمایش داده نشوند.
با تنظیم groupCollapse به true، در ابتدای نمایش گروه‌ها، ردیف‌های آن‌ها نمایش داده نخواهند شد و در حالت جمع شده قرار می‌گیرند.
groupSummary به معنای فعال سازی نمایش ردیف محاسبه‌ی summary مانند sum، min، max و امثال آن بر روی یک گروه است.
اگر مقدار showSummaryOnHide مساوی true باشد، ردیف محاسبه‌ی summary حتی در حالت groupCollapse: true نمایش داده خواهد شد.


فعال سازی محاسبه‌ی جمع ستون تعداد بار مشاهدات مطالب

برای فعال سازی نهایی محاسبه‌ی جمع ستون تعداد بار مشاهدات، علاوه بر تنظیم groupSummary به true، نیاز است در همان ستون مشخص کنیم که این محاسبات چگونه باید انجام شوند:
                colModel: [
// ........
                    {
                        name: '@(StronglyTyped.PropertyName<Post>(x => x.Title))',
                        index: '@(StronglyTyped.PropertyName<Post>(x => x.Title))',
                        align: 'right',
                        width: 150,
                        summaryTpl: '<div style="text-align: left;">خلاصه </div>',
                        summaryType: function (val, name, record) {
                            return "";
                        }
                    },
// ........
                    {
                        name: '@(StronglyTyped.PropertyName<Post>(x => x.NumberOfViews))',
                        index: '@(StronglyTyped.PropertyName<Post>(x => x.NumberOfViews))',
                        align: 'center',
                        width: 70,
                        summaryType: 'sum', summaryTpl: '<b>جمع مشاهدات: {0}</b>'
                    }
                ],
خاصیت summaryType نوع متد محاسبه‌ی summary مانند sum را مشخص می‌کند. خاصیت summaryTpl اختیاری است. اگر ذکر شود سبب فرمت مقدار محاسبه شده‌ی نهایی می‌گردد. در اینجا {0} به مقدار نهایی که قرار است در این سلول درج شود، اشاره می‌کند.
summaryType مانند ستون عنوان، سفارشی شده نیز می‌توان باشد. در ردیف summary و ستون عنوان تنها می‌خواهیم یک مقدار ثابت را نمایش دهیم، به همین جهت summaryType آن به یک مقدار خالی تنظیم شده‌است.


تغییر رنگ ردیف خلاصه عملیات هر گروه به همراه گشودن خودکار اولین گروه

گروه بندی به همراه یک سری متد توکار نیز هست. برای مثال اگر متد groupingToggle را بر روی Id هر گروه فراخوانی کنیم، می‌توان سبب باز یا بسته شده آن گروه شد. متدهای دیگری مانند groupingGroupBy برای گروه بندی پویا و groupingRemove برای حذف گروه بندی نیز وجود دارند:
            $('#list').jqGrid({
                caption: "آزمایش دهم",
                //.........
                loadComplete: function() {
                    //.........
                    $('#list').jqGrid('groupingToggle', 'list' + 'ghead_0_0');
                    $("tr.jqfoot td").css({
                        "background": "#2f4f4f",
                        "color": "#FFF"
                    });
                },
            });
بهترین محل اعمال رنگ به ردیف‌های summary، در روال رویدادگردان loadComplete گرید است.


مثال کامل این قسمت را از اینجا می‌توانید دریافت کنید:
jqGrid10.zip
نظرات مطالب
Blazor 5x - قسمت 14 - کار با فرم‌ها - بخش 2 - تعریف فرم‌ها و اعتبارسنجی آن‌ها
آیا نیاز هست که ورودی‌ها قبل از ارسال به بانک توسط HtmlSanitizer پالایش شوند؟ برای مثال چنین داده ای می‌تواند در بانک به راحتی ذخیره شود. در رابطه با QueryString‌ها چطور؟ آیا پالایش آن‌ها نیاز است؟
@"<script>alert('xss')</script><div onload=""alert('xss')"""
    + @"style=""background-color: rgba(0, 0, 0, 1)"">Test<img src=""test.png"""
    + @"style=""background-image: url(javascript:alert('xss')); margin: 10px""></div>";
در رابطه با SQL injection چطور؟ صرف اینکه از ORM استفاده می‌شود کفایت می‌کند یا اینکه بایستی کامندهای مربوط به SQL injection را تمیز کنیم؟
مطالب
C# 6 - Expression-Bodied Members
در ادامه مطالب منتشر شده در رابطه با قابلیت‌های جدید سی‌شارپ 6، در این مطلب به بررسی یکی دیگر از این قابلیت‌ها، با نام Expression-Bodied Members خواهیم پرداخت. در واقع در سی‌شارپ 6، هدف، ساده‌سازی سینتکس و افزایش بهره‌وری برنامه‌نویس می‌باشد. در نسخه‌های قبلی سی‌شارپ برای یکسری از اعمال روتین می‌بایستی روالی‌هایی را مدام تکرار می‌کردیم؛ به عنوان مثال در تعریف پراپرتی‌های یک کلاس در حالت get-only باید هر بار توسط return مقداری را برگردانیم:
public class Person
{
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public string FullName
   {
       get
       {
                return FirstName + " " + LastName;
       }
   }
}
نوشتن پراپرتی‌هایی همانند FullName منجر به نوشتن خطوط کد اضافه‌تری خواهد شد، هرچند می‌توان این حالت را با برداشتن خطوط اضافی بهبود بخشید:
public string FullName
{
       get { return FirstName + " " + LastName; }
}
اما در سی‌شارپ 6 میتوان آن را توسط expression body به یک خط کاهش داد!

استفاده از expression body برای پراپرتی‌های get-only (فقط خواندنی):

اگر در کلاس‌هایتان پراپرتی‌های get-only دارید، به راحتی می‌توانید بدنه‌ی پراپرتی را با استفاده از expression syntax خلاصه‌نویسی کنید. در واقع شما با استفاده از سینتکس lambda expression اقدام به نوشتن بدنه پراپرتی‌های موردنظرتان می‌کنید. یعنی به جای نوشتن کدی مانند:
{ get { return your expression; } }
به راحتی می‌توانید از سینتکس زیر استفاده نمائید:
=> your expression;
به عنوان مثال، میتوان پراپرتی FullName را در کلاس Person با کمک قابلیت expression body به صورت زیر بازنویسی کنیم:
public class Person
{
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public string FullName => FirstName + " " + LastName;
}
با کد فوق به راحتی توانستیم قسمت‌های اضافه‌ای را حذف کنیم. اکنون ممکن است بپرسید آیا این تغییر در performance برنامه تاثیری دارد؟ خیر؛ زیرا سینتکس فوق دقیقاً همان کد ILی را تولید خواهد کرد که در حالت عادی تولید می‌شود. همچنین delegateی را تولید نخواهد کرد؛ بلکه تنها از سینتکس lambda expression برای خلاصه‌نویسی بدنه پراپرتی استفاده می‌کند. در حال حاضر برای حالت setter سینتکسی ارائه نشده است.

استفاده از expression body برای Indexerها: 

همچنین از این قابلیت برای Indexerها نیز میتوان استفاده کرد، مثلاً به جای نوشتن کد زیر:
public string this[int number]
{
            get
            {
                if (number >= 0 && number < _values.Length)
                {
                    return _values[number];
                }
                return "Error";
            }
}
می‌توانیم کد فوق را به این صورت خلاصه‌نویسی کنیم:
public string this[int number] => (number >= 0 && number < _values.Length) ? _values[number] : "Error";
نکته: توجه داشته باشید که در هر دو حالت فوق تنها می‌توانیم برای get از expression body استفاده کنیم، هنوز سینتکسی برای حالت set ارائه نشده است.

استفاده از expression body برای متدها: 

برای متدها نیز می‌توانیم از قابلیت عنوان شده استفاده نمائیم، به عنوان مثال اگر داخل کلاس Person متد زیر را داشته باشیم:
public override string ToString()
{
      return FirstName;
}
می‌توانیم آن را به صورت زیر بنویسیم:
public override string ToString() => FirstName;
همانطور که مشاهده می‌کنید به جای نوشتن curly braces یا {} از lambda arrow یا <= استفاده کرده‌ایم. در اینجا عبارت سمت راست lambda arrow نمایانگر بدنه‌ی متد است. همچنین برای متدهای دارای پارامتر نیز به این صورت عمل می‌کنیم:
public int DoubleTheValue(int someValue) => someValue * 2;
یک عضو از کلاس که به صورت expression body نوشته شده باشد، expression bodied member نامیده می‌شود. این عضو از کلاس در ظاهر شبیه به عبارات لامبدای ناشناس (anonymous lambda expression) است. اما یک expression bodied member باید دارای نام، مقدار بازگشتی و بدنه متد باشد. 
تقریباً تمامی access modifierها در این حالت قابلیت استفاده را دارند. تنها متدهای abstract نمی‌توانند استفاده شوند.

محدودیت‌های Expression Bodied Members 
  • یکی از محدودیت‌های استفاده از expression body داشتن چندین خط دستور برای بدنه متدهایمان است. در اینحالت باید از روش سابق (statement body) استفاده نمائید. 
  • یکی دیگر از محدودیت‌ها عدم امکان استفاده از if, else, switch است. به عنوان مثال نمی‌توان کد زیر را با داشتن if و else به صورت expression body نوشت:
public override string ToString()
{
       if (MiddleName != null)
       {
                return FirstName + " " + MiddleName + " " + LastName;
       }
       else
       {
                return FirstName + " " + LastName;
       }
}
برای حالت فوق به عنوان یک روش جایگزین می‌توان از conditional operator استفاده کرد:
public override string ToString() =>
                    (MiddleName != null)
                    ? FirstName + " " + MiddleName + " " + LastName
                    : FirstName + " " + LastName;
  • همچنین نمی‌توان از for, foreach, while, do در expression body استفاده کرد، به جای آن می‌توان از عبارت‌های LINQ برای بدنه تابع استفاده کرد. به عنوان مثال متد زیر:
public IEnumerable<int> SmallNumbers()
{
    for (int i = 0; i < 10; i++)
        yield return i;
}
را می‌توان در حالت expression body به این صورت نوشت:
public IEnumerable<int> SmallNumbers() => from n in Enumerable.Range(0, 10)
                                                                         select n;
و یا به این صورت:
public IEnumerable<int> SmallNumbers() => Enumerable.Range(0, 10).Select(n => n);
  • همانطور که عنوان شد، استفاده از expression body در قسمت پراپرتی‌ها تنها محدود به پراپرتی‌های get-only (فقط خواندنی) میباشد.
  • استفاده از این قابلیت برای متدهای سازنده
  • استفاده در رخدادها
  • استفاده در finalizers
نکته: اگر می‌خواهید expression bodied member شما هم initializer داشته باشد و همچنین یک read only auto property باشد، باید مقداری سینتکس آن را تغییر دهید. همانطور که می‌دانید auto propertyها نیازی به backing field ندارند؛ بلکه در زمان کامپایل به صورت خودکار تولید خواهند شد. در نتیجه برای مقداردهی اولیه به backing fieldها می‌توانیم درون سازنده کلاس آنها را initialize کنیم:
    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public Person()
        {
            this.FirstName = "Sirwan";
            this.LastName = "Afifi";
        }
    }
برای نوشتن پراپرتی‌های فوق به صورت expression body می‌توانیم به این صورت عمل کنیم:
public string FirstName { get; set; } = "Sirwan";
public string LastName { get; set; } = "Afifi";
اگر ReSharper را نصب کرده باشید، به شما پیشنهاد می‌دهد که از expression body استفاده نمائید: :
برای حالت فوق:

برای پراپرتی‌ها:



مطالب
چه زمانی بهتر است از Silverlight استفاده شود؟

1- نیاز به توانایی‌های موجود در برنامه‌های Desktop را دارید اما همچنین نیاز است تا آن‌ها را تحت وب نیز ارائه دهید.
یکی از دلایل اقبال به برنامه‌های تحت وب در سازمان‌ها عدم نیاز به نصب آن‌ها و توزیع هر چه ساده‌تر اینگونه برنامه‌ها در شبکه است. تنها کافی است چند فایل را بر روی سرور به روز رسانی کنید و پس از آن تمام کلاینت‌ها از آخرین نگارش برنامه شما بهره‌مند خواهند شد (+). توزیع برنامه‌های سیلورلایت نیز به همین منوال است. علاوه بر آن استفاده از فناورهایی مانند MEF امکان ماژولار ساختن برنامه و دریافت آخرین ماژول‌های تهیه شده (فایل‌های XAP مجزای از برنامه به صورت افزونه) را بر اساس انتخاب و سطح دسترسی کاربر نیز میسر می‌سازد.

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

3- برنامه‌ی شما نیاز است تا از طریق وب توزیع شود اما نیاز به سطح دسترسی بیشتری نسبت به یک برنامه‌ی وب معمولی دارد.
تمام برنامه‌های توزیع شده از طریق مرورگرها محدود به سطوح دسترسی آن‌ها نیز هستند. اما امکان نصب خارج از مرورگر برنامه‌های سیلورلایت نیز وجود دارد. در این حالت می‌توان در صورت نیاز و همچنین تائید صریح کاربر، به سطوح دسترسی بیشتری دست یافت. برای مثال دسترسی به اسکنر در یک برنامه‌ی وب متداول بی‌معنا است. اما سیلورلایت 4 در حالت اجرای در خارج از مرورگر امکان تعامل با اشیاء COM را نیز دارد.

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

5- از مشکلات مدیریت حالت در برنامه‌های متداول وب به تنگ آمده‌اید.
اگر برای مثال برنامه نویس ASP.NET باشید حتما با مباحث State management آشنایی دارید (از سشن و کوکی گرفته تا ViewState (ایی که همه به نحوی قصد کوچک کردن آن‌را دارند!) و غیره). تمام این‌ها هم برای این است که بتوان تجربه‌ی کاری برنامه‌های دسکتاپ را در محیط مرورگرها شبیه سازی کرد. این مشکلات در سیلورلایت حل شده است. یک برنامه‌ی سیلورلایت State full است نه Stateless . همچنین اگر از حافظه‌ای هم استفاده می‌کند این مورد در سمت کاربر است و نه سمت سرور و نه منقضی شدن زود هنگام سشن‌ها و صدها ترفند برای مقیاس پذیری همین مساله‌ی بسیار کوچک با تعداد کاربران بالا در برنامه‌های متداول وب.
به عبارتی تصور کنید که برنامه‌ی دسکتاپ سال‌های قبل شما هم اکنون داخل مرورگر دارد اجرا می‌شود و چیزی به نام وب سرور وجود ندارد که پس از نمایش صفحه‌ی وب شما، کلیه‌ی اشیاء مرتبط با آن‌را در سمت سرور تخریب کند چون باید پاسخگوی کاربران همزمان بی‌شماری باشد و منابع سرور هم محدود است. (سیلورلایت یک فناوری سمت کاربر است. بنابراین وب سرور صرفا نقش توزیع آن‌را به عهده دارد یا حداکثر ارائه‌ی یک وب سرویس جهت تعاملات بعدی مانند کار با بانک اطلاعاتی)

6- نیاز دارید تا برنامه‌ی وب شما تحت تمام مرورگرها به یک شکل به نظر برسد و همچنین رفتار یکسانی هم داشته باشد.
هیچ وقت روزی را فراموش نمی‌کنم که حین پرداخت الکترونیکی بانک XYZ به کمک مرورگر فایرفاکس، دکمه‌ی پرداخت در مرحله‌ی آخر، کار نمی‌کرد! هر چقدر روی آن کلیک می‌کردم اتفاقی نمی‌افتاد! تراکنش برگشت خورد و همین خرید ساده با مرورگر IE به سادگی انجام شد.
با سیلورلایت این مشکلات را نخواهید داشت زیرا کار نمایش برنامه شما توسط افزونه‌ی مربوطه صورت می‌گیرد و این افزونه مستقل است از نوع مرورگر شما.

7- نیاز است برنامه‌ی وب شما در حالت آفلاین هم کار کند.
برنامه‌های سیلورلایت تنها زمانیکه نیاز به دریافت یا ثبت اطلاعاتی از سرور داشته باشند، باید آنلاین باشند. همچنین این برنامه‌ها دسترسی به مفهوم جدیدی به نام Isolated Storage دارند که در آن می‌توان اطلاعات را به ازای هر کاربر آن هم با ضریب امنیتی بالا بر روی هارد شخص ذخیره کرد و زمان آنلاین شدن برنامه آن‌ها را به سرور انتقال داد.

8- برنامه وب شما نیاز است تا با فایل‌های مالتی مدیا تعامل داشته و آن‌ها را پخش کند.
حتی تگ Video در HTML5 نیز به پای توانایی‌های مالتی مدیا در Silverlight مانند smooth streaming, multicasting, editing, video brushes نمی‌رسد. برای مثال با استفاده از video brushes می‌توان یک فایل ویدیویی در حال پخش را بر روی یک وجه یک شیء در حال پویانمایی نقاشی و نمایش داد.

9- نیاز به پشتیبانی از multi-touch در برنامه‌ی وب شما وجود دارد.
برخلاف HTML ، تعاملات multi-touch در Silverlight میسر است.

10- نیاز به ایجاد برنامه‌های بازی تحت وب دارید.
به طور قطع می‌توان بازیی‌هایی در حد Pong را با جاوا اسکریپت هم ایجاد کرد، اما اگر نیاز به تولید بازی‌هایی جدی‌تر وجود داشت برای مثال انتقال بازی Quake به محیط وب، Silverlight در این زمینه هم حرف‌های زیادی برای گفتن دارد (+).

11- نیاز به تولید برنامه‌ی دسکتاپ چند سکویی دارید.
سیلورلایت هم اکنون تحت ویندوز، MAC OS-X ، لینوکس و ... پشتیبانی می‌شود (+). همچنین برنامه‌های سیلورلایت قابلیت اجرای در خارج از مرورگر را هم دارند.
با سیلورلایت دیگر نیازی نخواهد بود تا کاربران لینوکسی ابتدا Wine را نصب کنند تا بتوانند از یک برنامه‌ی ویندوزی که انتقال پذیر نیست در لینوکس هم بتوانند استفاده کنند؛ چون پروژه‌ی مون لایت لینوکسی برای این منظور مهیا است.

12- نیاز به تولید برنامه‌های تحت وب سریع و با کارآیی بالا دارید.
فایل‌های نهایی Silverlight با توجه به ماهیت کامپایل شده‌ی آن‌ها به طور قطع از کدهای جاوا اسکریپتی سمت کلاینت که باید توسط مرورگر تفسیر و پردازش شوند (و هر کدام هم از موتور خاص خودشان استفاده می‌کنند)، سریعتر اجرا می‌شوند (+).

13- از پیچیدگی‌های پیاده سازی برنامه‌های متداول وب خسته شده‌اید.
هنوز هم با تمام پیشرفت‌های حاصل، تولید برنامه‌های وب پیشرفته مشکل است. از یک طرف ناسازگاری یک سری از مرورگرها با یک سری از قابلیت‌ها را باید در نظر داشت، تا فراگیری فریم ورک‌های Ajax و غیره تا مشکل بودن طراحی کنترل‌های جدید فراتر از آن چیزی که HTML استاندارد ارائه می‌دهد. بله، به طور قطع دانش فنی بالایی در این زمینه در طی سالیان تولید شده است، اما باز هم فراگیری و تسلط به آن‌ها زمان قابل توجهی را طلب می‌کند.
در سیلورلایت کلیه تعاملات با شبکه به صورت پیش فرض غیرهمزمان است (همان ایده‌ی اصلی Ajax) همچنین با توجه به state full بودن اینگونه برنامه‌ها، عملا برنامه نویس‌ها بدون درگیر شدن با مفاهیم اجکسی و مدیریت حالت، برنامه‌ی پیشرفته‌ی وبی را در مدت زمان کوتاهی تولید کرده‌اند و این برنامه در تمام مرورگرهایی که قابلیت بارگذاری افزونه‌ی سیلورلایت را دارند به یک شکل و کیفیت اجرا می‌شود.

14- در زمینه میزان مصرف پهنای باند ملاحظاتی ویژه‌ای وجود دارد.
یک برنامه‌ی سیلورلایت تنها یکبار باید دریافت شود. پس از آن در سمت کاربر کش خواهد شد (تا زمان به روز رسانی بعدی برنامه در سرور). همین مساله در دفعات بعدی مراجعه کاربر به سایت نقش قابل توجهی را در کاهش میزان مصرف پهنای باند (یا به قولی میزان کمتر data transfer) کلی دارد.

15- فرصت کافی برای فراگیری انبوهی از فناوری‌های مختلف را ندارید!
بله! برای ایجاد یک برنامه‌ی تحت وب که کاربر آن پس از مشاهده بگوید WOW نیاز است به HTML ، JS ، CSS ، AJAX ، یکی از فناوری‌های سمت سرور و ... مسلط بود (علاوه بر اینکه باید بدانید فلان کد JS در IE کار می‌کند اما در فایرفاکس خیر. فایرفاکس فلان قسمت CSS را پشتیبانی می‌کند اما IE خیر! و ...).
اما برای استفاده از سیلورلایت فقط کافی است به XAML و یکی از زبان‌های دات نت مانند سی شارپ یا VB.NET مسلط باشید (البته هیچ وقت از دست ASP.NET خلاص نخواهید شد! حداقل در حد راه اندازی یک وب سرویس یا مفاهیم امنیتی آن).
این مورد خصوصا برای افرادی که برنامه نویس دسکتاپ هستند اما علاقمندند تا برنامه‌ی وب نیز تولید کنند بسیار مهم است. با حداقل آموزش می‌توانند توانایی‌های خود را به وب نیز گسترش دهند. علاوه بر آن عمده‌ی دانش Silverlight شما جهت تولید برنامه‌های WPF (با توجه به اینکه Silverlight فرزند WPF محسوب می‌شود) یا Windows phone 7‌ و غیره نیز می‌تواند بکار گرفته شود.

16- نیاز به اجرای کدهای چند ریسمانی در سمت کاربر دارید.
تا این لحظه پشتیبانی رسمی از مباحث چند ریسمانی در JavaScript و استانداردهای مرتبط با آن وجود ندارد. Silverlight به اکثر امکانات Threading موجود در دات نت فریم ورک دسترسی داشته و دانش فعلی شما قابل انتقال است.


و دست آخر باید به نکته اشاره کرد که هدف از Silverlight ساخت وب سایت معمولی نیست. این نوع کارها را با همان ابزارهای متداول انجام دهید. هدف اصلی آن ساخت برنامه است (Application در مقابل Web site). مشتری‌های اصلی این نوع برنامه‌ها هم بیشتر سازمان‌ها و اینترانت‌های پر سرعت و بسته‌ی آن‌ها هستند که نه نگران حجم افزونه‌ی سیلورلایت هستند و نه مشکلی با حجم برنامه‌ی سیلورلایت شما در یک شبکه‌ی داخلی پر سرعت دارند.

اشتراک‌ها
Bootstrap 5.1.2 منتشر شد

Bootstrap v5.1.2 is here with a handful of improvements across our components, plus a fix for an issue in another project that prevented our Sass from compiling properly. Keep reading for the highlights. 

Bootstrap 5.1.2 منتشر شد
مطالب
استفاده از #F در پروژه های WPF
در دوره #F این سایت (^) با نحوه کد نویسی و مفاهیم و مزایای این زبان آشنا شده اید. اما دانستن syntax یک زبان برای پیاده سازی یک پروژه کافی نیست و باید با تکنیک‌های مهم دیگر از این زبان آشنا شویم. همان طور که قبلا (فصل اول دوره #F) بیان شد Visual Studio به صورت Visual از پروژه‌های #F پشتیبانی نمی‌کند. یعنی امکان ایجاد یک پروژه WPF یا Windows Application یا حتی پروژه‌های تحت وب برای این زبان همانند زبان #C به صورت Visual در VS.Net تعبیه نشده است. حال چه باید کرد؟ آیا باید در این مواقع این گونه پروژه‌ها را با یک زبان دیگر نظیر #C ایجاد کنیم و از زبان #F در حل برخی مسائل محاسباتی و الگوریتمی استفاده کنیم. این اولین راه حلی است که به نظر می‌رسد. اما در حال حاضر افزونه هایی، توسط سایر تیم‌های برنامه نویسی تهیه شده اند که پیاده سازی و اجرای یک پروژه تحت ویندوز یا وب را به صورت کامل با زبان #F امکان پذیر می‌کنند. در  این پست به بررسی یک مثال از پروژه WPF به کمک این افزونه‌ها می‌پردازیم.

نکته : آشنایی با کد نویسی و مفاهیم #F برای درک بهتر مطالب توصیه می‌شود.

معرفی پروژه FSharpX

پروژه FSharpx یک پروژه متن باز است که توسط یک تیم بسیار قوی از برنامه نویسان #F در حال توسعه می‌باشد. این پروژه شامل چندین زیر پروژه و بخش است که هر بخش آن برای یکی از مباحث دات نت در #F تهیه و توسعه داده می‌شود.
این قسمت‌ها عبارتند از :
FSharpx.Core : شامل مجموعه ای کامل از توابع عمومی، پرکاربرد و ساختاری است که برای این زبان توسعه داده شده اند و با تمام زبان‌های دات نت سازگاری دارند؛
FSharpx.Http : استفاده از #F در برنامه نویسی مدل Http؛
FSharpx.TypeProvider : این پروژه خود شامل چندین بخش است که در این جا چند مورد از آن‌ها را عنوان می‌کنم:
  • FSharpx.TypeProviders.AppSetting : متد خواندن و نوشتن (setter  و getter) را برای فایل‌های تنظیمان پروژه (Application Setting File) فراهم می‌کند.
  • FSharpx.TypeProviders.Vector : برای محاسبات با ساختار‌های برداری استفاده می‌شود.
  • FSharpx.TypeProviders.Machine : برای دسترسی و اعمال تغییرات در رجیستری و فایل‌های سیستمی استفاده می‌شود.
  • FSharpx.TypeProviders.Xaml : با استفاده از این افزونه می‌توانیم از فایل‌های Xaml، در پروژه‌های #F استفاده کنیم و WPF Designer نرم افزار VS.Net هم برای این زبان قابل استفاده خواهد شد.
  • FSharpx.TypeProviders.Regex : امکان استفاده از عبارات با قاعده را در این پروژه فراهم می‌کند.

یک مثال از عبارات با قاعده:

type PhoneRegex = Regex< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{4}$)">

PhoneRegex.IsMatch "425-123-2345"
|> should equal true

PhoneRegex().Match("425-123-2345").CompleteMatch.Value
|> should equal "425-123-2345"

PhoneRegex().Match("425-123-2345").PhoneNumber.Value
|> should equal "123-2345"
َشروع پروژه
ایتدا یک پروژه از نوع F# Console Application ایجاد کنید. از قسمت Project Properties (بر روی پروژه کلیک راست کنید و گزینه Properties را انتخاب کنید) نوع پروژه را به Windows Application تغییر دهید(قسمت Out Put Type). اسمبلی‌های زیر را به پروژه ارجاع دهید:
  • PresentationCore
  • PresentationFramework
  • WindowBase
  • System.Xaml

با استفاده از پنجره Package Manager Console دستور نصب زیر را اجرا کنید(آخرین نسخه این پکیج 1.8.31  و حجم آن کمتر از یک مگابایت است):

PM> Install-Package FSharpx.TypeProviders.Xaml

حال یک فایل Xaml به پروژه اضافه کنید و کد‌های زیر را در آن کپی کنید:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF F# Sample By Masoud Pakdel" Height="350" Width="525">
    <Grid Name="MainGrid">
        <StackPanel Name="StackPanel1" Margin="50">
            <Button Name="Button1">Who are you?</Button>        
        </StackPanel>
    </Grid>
</Window>
کد‌های بالا کاملا واضح است و نیاز به توضیح دیده نمی‌شود. اما اگر دقت کنید می‌بینید که این فایل، فایل Code Behind ندارد. برای این کار باید یک فایل جدید از نوع F# Source File ایجاد کنید. بهتر است که فایل جدید شما همنام با همین فایل باشد. پسوند این فایل fs است. حال کد‌های زیر را در آن کپی کنید:
open System
open System.Windows
open System.Windows.Controls
open FSharpx
 
type MainWindow = XAML<"MainWindow.xaml">
 
let loadWindow() =
    let window = MainWindow()
    window.Button1.Click.Add(fun _ ->
        MessageBox.Show("Masoud Pakdel")
        |> ignore)
    window.Root
 
[<STAThread>]
(new Application()).Run(loadWindow())
|> ignore
نوع XAML استفاده شده  که به صورت generic است در فضای نام FSharpx تعبیه شده است و این اجازه را می‌دهد که یک فایل #F بتواند برای مدیریت یک فایل Xaml  استفاده شود.برای مثال می‌توانید به اشیا و خواص موجود در فایل Xaml دسترسی داشته باشید. در اینجا دیگر خبری از متد InitializeComponent موجود در سازنده کلاس CodeBehind پروژه‌های #C نیست. این تعاریف و آماده سازی کامپوننت‌ها به صورت توکار در نوع XAML موجود در FSharpx انجام می‌شود.


در تابع loadWindow یک نمونه از کلاس MainWindow ساخته می‌شود و برای button1 آن رویداد کلیک تعریف می‌کنیم. دستورات زیر معادل دستورات شروع برنامه در فایل program پروژه‌های #C است.
[<STAThread>]
(new Application()).Run(loadWindow())
|> ignore

پروژه را اجرا کنید و بر روی تنهای Button موجود در صفحه، کلیک کنید و پیغام مورد نظر را مشاهده خواهید کرد. به صورت زیر:

مطالب
PowerShell 7x - قسمت اول - معرفی و نصب
PowerShell یک ابزار task automation است که همزمان یک command-line shell، زبان اسکریپتی و یک فریم‌ورک configuration management نیز میباشد. برخلاف دیگر shellها که مبتنی بر رشته هستند، ورودی و خروجی آن اشیاء دات‌نتی است و از آنجائیکه مبتنی بر CLR میباشد، امکان نوشتن توابع، کلاس‌ها و ماژول‌ها را به ما میدهد. همچنین به صورت توکار امکان کار با فرمت‌هایی از قبیل CSV, XML, JSON را در اختیارمان قرار میدهد. بخاطر extensible بودن، تعداد زیادی ماژول و افزونه برای نصب وجود دارند که کار با انواع تکنولوژی‌ها را میسر میسازند: 
  • Azure
  • Windows
  • Exchange
  • SQL
  • AWS
  • VMWare
  • Google Cloud
PowerShell در ابتدا در سال 2006 برای ویندوز XP به همراه 130 کامند ارائه شد. نسخه‌های بعدی آن نیز به ترتیب 2.0, 3.0, 4.0, 5.0 و در نهایت 5.1 به همراه تعداد بیشتری از Commandها ارائه شدند. تا اینجا فقط بر روی ویندوز استفاده بود، چون براساس Full .NET Framework توسعه داده شده بود، تا در نهایت در سال 2018 نسخه cross-platform آن یعنی نسخه 6.0 ارائه شد که مبتنی بر .NET Core 2 بود. در نسخه 6.2 تعداد Commandها به نصف تعداد نسخه 5.0 هم نمیرسید. در نهایت نسخه 7.0 ارائه شد که هم backward compatible بود و هم اینکه به صورت cross-platform نیز ارائه شد؛ لازم به ذکر است، این نسخه از PowerShell براساس .NET Core 3 توسعه یافت. PowerShell به صورت پیش‌فرض بر روی ویندوز ۷ (همچنین ویندوز ۲۰۰۸) به بعد، قابل نصب است. لازم به ذکر است که اسم پراسس PowerShell از نسخه ۷ به بعد از powershell.exe به pwsh.exe تغییر نام یافته است. بنابراین به صورت side-by-side در کنار PowerShell 5.1 قابل نصب است.


ISE یا همان Integrated Scripting Environment در واقع همان IDE برای نوشتن اسکریپت‌های چندخطی PowerShell است. از نسخه ۷ به بعد، PowerShell دیگر با ISE ارائه نمیشود و فقط برای ویندوز و در support mode است: 


برای نوشتن اسکریپت‌های PowerShell بهتر است extension رسمی آن را نصب کنید (+). با نصب این extension، محیط VSCode ظاهری شبیه به ISE پیدا خواهد کرد (البته به صورت پیش‌فرض فعال نیست و باید بعد از نصب theme را تغییر دهید). همچنین از Language Server مربوط به PowerShell نیز استفاده میکند که نوشتن و دیباگ کردن اسکریپت‌های PowerShell را به مراتب ساده‌تر خواهد کرد:
 

همچنین قابلیت IntelliSense  را نیز ارائه میدهد:

یکسری قابلیت‌های دیگر هم به همراه این extension به VSCode اضافه میشوند؛ به عنوان مثال PowerShell Script Analyzer نیز نصب خواهد شد که برای بررسی کیفیت کدها بسیار مفید است.


در اینجا میتوانید لیست کامل این ruleها را مشاهده کنید. از دیگر قابلیت‌های این extension میتوان به موارد زیر اشاره کرد:
  • Syntax highlighting
  • Code snippets
  • IntelliSense for cmdlets and more
  • Rule-based analysis provided by PowerShell Script Analyzer
  • Go to Definition of cmdlets and variables
  • Find References of cmdlets and variables
  • Document and workspace symbol discovery
  • Run selected selection of PowerShell code using F8
  • Launch online help for the symbol under the cursor using Ctrl+F1
  • Local script debugging
  • Extension Terminal support
  • PowerShell ISE color theme 

نصب PowerShell بر روی macOS 
نصب PowerShell به چند طریق قابل انجام است که در اینجا میتوانید مشاهده کنید؛ به عنوان مثال برای نصب PowerShell روی macOS تنها کافی است دستور زیر را وارد کنید: 
brew install --cask powershell
سپس دستور pwsh قابل استفاده خواهد بود: 
❯ pwsh
PowerShell 7.2.6
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

PS />

در قسمت‌های بعدی، مقدمات کار با PowerShell را توضیح خواهیم داد.
مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 22 - توزیع برنامه توسط IIS
روش کار برنامه‌های ASP.NET Core در IIS کاملا متفاوت است با تمام نگارش‌های پیشین ASP.NET؛ از این جهت که برنامه‌های ASP.NET Core در اصل یک برنامه‌ی متکی به خود از نوع Console می‌باشند. به همین جهت برای هاست شدن نیازی به IIS ندارند. این نوع برنامه‌ها به همراه یک self-hosted Web server ارائه می‌شوند (به نام Kestrel) و این وب سرور توکار است که تمام درخواست‌های رسیده را دریافت و پردازش می‌کند. هرچند در اینجا می‌توان از IIS صرفا به عنوان یک «front end proxy» استفاده کرد؛ از این جهت که Kestrel تنها یک وب سرور خام است و تمام امکانات و افزونه‌های مختلف IIS را شامل نمی‌شود.
بر روی ماشین‌های ویندوزی و ویندوزهای سرور، استفاده‌ی از IIS به عنوان پروکسی درخواست‌ها و ارسال آن‌ها به Kestrel، روش توصیه شده‌است؛ از این جهت که حداقل قابلیت‌هایی مانند «port 80/443 forwarding»، مدیریت طول عمر برنامه، مدیریت مجوزهای SLL آن و خیلی از موارد دیگر توسط Kestrel پشتیبانی نمی‌شود.


معماری پردازش نگارش‌های پیشین ASP.NET در IIS


در نگارش‌های پیشین ASP.NET، همه چیز داخل پروسه‌‌ای به نام w3wp.exe و یا IIS Worker Process پردازش می‌شود که در اصل چیزی نیست بجز همان IIS Application Pool. این AppPoolها، برنامه‌های ASP.NET شما را هاست می‌کنند و همچنین سبب وهله سازی و اجرای آن‌ها نیز خواهند شد.
در اینجا درایور http.sys ویندوز، درخواست‌های رسیده را دریافت کرده و سپس آن‌ها را به سمت سایت‌هایی نگاشت شده‌ی به AppPoolهای مشخص، هدایت می‌کند.


معماری پردازش برنامه‌های ASP.NET Core در IIS

روش اجرای برنامه‌های ASP.NET Core با نگارش‌های پیشین آن‌ها کاملا متفاوت هستند؛ از این جهت که داخل پروسه‌ی w3wp.exe اجرا نمی‌شوند. این برنامه‌ها در یک پروسه‌ی مجزای کنسول خارج از پروسه‌ی w3wp.exe اجرا می‌شوند و حاوی وب سرور توکاری به نام کسترل (Kestrel) هستند.


 این وب سرور، وب سروری است تماما دات نتی و به شدت برای پردازش تعداد بالای درخواست‌ها بهینه سازی شده‌است؛ تا جایی که کارآیی آن در این یک مورد چند 10 برابر IIS است. هرچند این وب سرور فوق العاده سریع است، اما «تنها» یک وب سرور خام است و به همراه سرویس‌های مدیریت وب، مانند IIS نیست.


در تصویر فوق مفهوم «پروکسی» بودن IIS را در حین پردازش برنامه‌های ASP.NET Core بهتر می‌توان درک کرد. ابتدا درخواست‌های رسیده به IIS می‌رسند و سپس IIS آن‌ها را به طرف Kestrel هدایت می‌کند.
برنامه‌های ASP.NET Core، برنامه‌های کنسول متکی به خودی هستند که توسط دستور خط فرمان dotnet اجرا می‌شوند. این اجرا توسط ماژولی ویژه به نام AspNetCoreModule در IIS انجام می‌شود.


همانطور که در تصویر نیز مشخص است، AspNetCoreModule یک ماژول بومی IIS است و هنوز برای اجرا نیاز به IIS Application Pool دارد؛ با این تفاوت که در تنظیم AppPoolهای برنامه‌های ASP.NET Core، باید NET CLR Version. را به No managed code تنظیم کرد.


اینکار از این جهت صورت می‌گیرد که IIS در اینجا تنها نقش یک پروکسی هدایت درخواست‌ها را به پروسه‌ی برنامه‌ی حاوی وب سرور Kestrel، دارد و کار آن وهله سازی NET Runtime. نیست. کار AspNetCoreModule این است که با اولین درخواست رسیده‌ی به برنامه‌ی شما، آن‌را بارگذاری کند. سپس درخواست‌های رسیده را دریافت و به سمت برنامه‌ی ASP.NET Core شما هدایت می‌کند (به این عملیات reverse proxy هم می‌گویند).


اگر دقت کرده باشید، برنامه‌های ASP.NET Core، هنوز دارای فایل web.config ایی با محتوای ذیل هستند:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*"
           modules="AspNetCoreModule" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%"
                arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false"
                stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
  </system.webServer>
</configuration>
توسط این تنظیمات است که AspNetCoreModule فایل‌های dll برنامه‌ی شما را یافته و سپس برنامه را به عنوان یک برنامه‌ی کنسول بارگذاری می‌کند (با توجه به اینکه حاوی کلاس Program و متد Main هستند).
یک نکته: در زمان publish برنامه، تنظیم و تبدیل مقادیر LAUNCHER_PATH و LAUNCHER_ARGS به معادل‌های اصلی آن‌ها صورت می‌گیرد (در ادامه مطلب بحث خواهد شد).


آیا واقعا هنوز نیازی به استفاده‌ی از IIS وجود دارد؟

هرچند می‌توان Kestrel را توسط یک IP و پورت مشخص، عمومی کرد و استفاده نمود، اما حداقل در ویندوز چنین توصیه‌ای نمی‌شود و بهتر است از IIS به عنوان یک front end proxy استفاده کرد؛ به این دلایل:
- اگر می‌خواهید چندین برنامه را بر روی یک وب سرور که از طریق پورت‌های 80 و 443 ارائه می‌شوند داشته باشید، نمی‌توانید از Kestrel  به صورت مستقیم استفاده کنید؛ زیرا از مفهوم host header routing که قابلیت ارائه‌ی چندین برنامه را از طریق پورت 80 و توسط یک IP میسر می‌کند، پشتیبانی نمی‌کند. برای اینکار نیاز به IIS و یا در حقیقت درایور http.sys ویندوز است.
- IIS خدمات قابل توجهی را به برنامه‌ی شما ارائه می‌کند. برای مثال با اولین درخواست رسیده، به صورت خودکار آن‌را اجرا و بارگذاری می‌کند؛ به همراه تمام مدیریت‌های پروسه‌ای که در اختیار برنامه‌های ASP.NET در طی سالیان سال قرار داشته‌است. برای مثال اگر پروسه‌ی برنامه‌ی شما در اثر استثنایی کرش کرد، دوباره با درخواست بعدی رسیده، حتما برنامه را بارگذاری و آماده‌ی خدمات دهی مجدد می‌کند.
- در اینجا می‌توان تنظیمات SSL را بر روی IIS انجام داد و سپس درخواست‌های معمولی را به Kestrel  ارسال کرد. به این ترتیب با یک مجوز می‌توان چندین برنامه‌ی Kestrel را مدیریت کرد.
- IISهای جدید به همراه ماژول‌های بومی بسیار بهینه و کم مصرفی برای مواردی مانند gzip compression of static content, static file caching, Url Rewriting هستند که با فعال سازی آن‌ها می‌توان از این قابلیت‌ها، در برنامه‌های ASP.NET Core نیز استفاده کرد.


نحوه‌ی توزیع برنامه‌های ASP.NET Core به IIS

روش اول: استفاده از دستور خط فرمان dotnet publish

برای این منظور به ریشه‌ی پروژه‌ی خود وارد شده و دستور dotnet publish را با توجه به پارامترهای ذیل اجرا کنید:
 dotnet publish --framework netcoreapp1.0 --output "c:\temp\mysite" --configuration Release
در اینجا برنامه کامپایل شده و همچنین مراحلی که در فایل project.json نیز ذکر شده‌اند، اعمال می‌شود. برای مثال در اینجا پوشه‌ها و فایل‌هایی که در قسمت include ذکر شده‌اند به خروجی کپی خواهند شد. همچین در قسمت scripts تمام مراحل ذکر شده مانند یکی کردن و فشرده سازی اسکریپت‌ها نیز انجام خواهد شد. قسمت postpublish تنها کاری را که انجام می‌دهد، ویرایش فایل web.config برنامه و تنظیم LAUNCHER_PATH و LAUNCHER_ARGS آن به مقادیر واقعی آن‌ها است.
{

    "publishOptions": {
        "include": [
            "wwwroot",
            "Features",
            "appsettings.json",
            "web.config"
        ]
    },
 
    "scripts": {
        "precompile": [
            "dotnet bundle"
        ],
        "prepublish": [
            //"bower install"
        ],
        "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
    }
}
و در نهایت اگر به پوشه‌ی output ذکر شده‌ی در فرمان فوق مراجعه کنید، این خروجی نهایی است که باید به صورت دستی به وب سرور خود برای اجرا انتقال دهید که به همراه تمام DLLهای مورد نیاز برای برنامه نیز هست.


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


برنامه‌های ASP.NET Core باید به AppPool ایی تنظیم شوند که NET CLR Version. آن‌ها No Managed Code است. همچنین بهتر است به ازای هر برنامه‌ی جدید یک AppPool مجزا را ایجاد کنید تا کرش یک برنامه تاثیر منفی را بر روی برنامه‌ی دیگری نگذارد.

روش دوم: استفاده از ابزار Publish خود ویژوال استودیو

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


در صفحه‌ی بعدی اگر گزینه‌ی file system را انتخاب کنید، دقیقا همان مراحل روش اول تکرار می‌شوند:


سپس می‌توانید فریم ورک برنامه و نوع ارائه را مشخص کنید:


و در آخر کار، Publish به این پوشه‌ی مشخص شده که به صورت پیش فرض در ذیل پوشه‌ی bin برنامه‌است، صورت می‌گیرد.


روش عیب یابی راه اندازی اولیه‌ی برنامه‌های ASP.NET Core

در اولین سعی در اجرای برنامه‌ی ASP.NET Core بر روی IIS به این خطا رسیدم:


در event viewer ویندوز چیزی ثبت نشده بود. اولین کاری را که در این موارد می‌توان انجام داد به این صورت است. از طریق خط فرمان به پوشه‌ی publish برنامه وارد شوید (همان پوشه‌ای که توسط IIS عمومی شده‌است). سپس دستور dotnet prog.dll را صادر کنید. در اینجا prog.dll نام dll اصلی برنامه یا همان نام پروژه است:


همانطور که مشاهده می‌کنید، برنامه به دنبال پوشه‌ی bower_components ایی می‌گردد که کار publish آن انجام نشده‌است (این پوشه در تنظیمات آغازین برنامه عمومی شده‌است و در لیست include قسمت publishOptions فایل project.json فراموش شده‌است).

روش دوم، فعال سازی stdoutLogEnabled موجود در فایل وب کانفیگ، به true است. در اینجا web.config نهایی تولیدی توسط عملیات publish را مشاهده می‌کنید که در آن پارامترهای  processPath و arguments مقدار دهی شده‌اند (همان قسمت postpublish فایل project.json). در اینجا مقدار stdoutLogEnabled به صورت پیش فرض false است. اگر true شود، همان خروجی تصویر فوق را در پوشه‌ی logs خواهید یافت:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\Core1RtmEmptyTest.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
  </system.webServer>
</configuration>
البته اگر کاربر منتسب به AppPool برنامه، دسترسی نوشتن در این پوشه را نداشته باشد، خطای ذیل را در event viewer ویندوز مشاهده خواهید کرد:
 Warning: Could not create stdoutLogFile \\?\D:\Prog\1395\Core1RtmEmptyTest\src\Core1RtmEmptyTest\bin\Release\PublishOutput\logs\stdout_10064_201672893654.log, ErrorCode = -2147024893.
همچنین پوشه‌ی logs را هم باید خودتان از پیش ایجاد کنید. به عبارتی کاربر منتسب به AppPool برنامه باید دسترسی نوشتن در پوشه‌ی logs واقع در ریشه‌ی برنامه را داشته باشد. این کاربر  IIS AppPool\DefaultAppPool نام دارد.



حداقل‌های یک هاست ویندوزی که می‌خواهد برنامه‌های ASP.NET Core را ارائه دهد

پس از نصب IIS، نیاز است ASP.NET Core Module نیز نصب گردد. برای این‌کار اگر بسته‌ی NET Core Windows Server Hosting. را نصب کنید، کافی است:
https://go.microsoft.com/fwlink/?LinkId=817246

این بسته به همراه NET Core Runtime, .NET Core Library. و ASP.NET Core Module است. همچنین همانطور که عنوان شد، برنامه‌های ASP.NET Core باید به AppPool ایی تنظیم شوند که NET CLR Version. آن‌ها No Managed Code است. این‌ها حداقل‌های راه اندازی یک برنامه‌ی ASP.NET Core بر روی سرورهای ویندوزی هستند.


هنوز فایل app_offline.htm نیز در اینجا معتبر است

یکی از خواص ASP.NET Core Module، پردازش فایل خاصی است به نام app_offline.htm. اگر این فایل را در ریشه‌ی سایت قرار دهید، برنامه پردازش تمام درخواست‌های رسیده را قطع خواهد کرد و سپس پروسه‌ی برنامه خاتمه می‌یابد. هر زمانیکه این فایل حذف شد، مجددا با درخواست بعدی رسیده، برنامه آماده‌ی پاسخگویی می‌شود.