در پروژههای ویندوزی یکی از بیشترین ابزار کاربردی گریدویو تلریک Telerik
GridView میباشد و اینکه تمامی امکانات گرید مانند گروه بندی ، فیلترینگ و
... همه فارسی باشند خیلی برای پروژه خوب است.
منم در یکی از پروژهها نیاز به فارسی کردن این ابزار پرکاربرد ویندوزی داشتم و توانستم این مورد
را حل کنم . نحوه فارسی کردن این ابزار به شرح ذیل میباشد:
1- یک پروژه جدید ویندوزی در visual studio ایجاد میکنیم
2- اضافه کردن یک radGridView به فرم و خاصیت Dock آن را به حالت Fill و خاصیت RightToLeft را Yes قرار میدهیم :
3- حال برای اینکه یک سری اطلاعاتی داخل این گرید نمایش بدهیم یک کلاس در همان فرم درست میکنیم مشابه کد ذیل :
public List<MyCustomData> GetData() { List<MyCustomData> myList = new List<MyCustomData>(); for (int i = 1; i < 11; i++) { myList.Add(new MyCustomData() { ID = i, Name = "Name Family " + i.ToString(), Age = 29 }); } return myList; } public class MyCustomData { public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } public bool Sex { get; set; } }
4 - حال برای اینکه این اطلاعات را در گرید نمایش دهیم کد زیر را در بخش Load_Form1 مینویسیم :
private void Form1_Load(object sender, EventArgs e) { radGridView1.DataSource = GetData(); }
6 - برای اینکه این موارد فارسی شوند نیاز به یک کلاس یا Provider داریم که این عمل ترجمه را انجام دهد که حتی در سایت خود تلریک در بخش مربوطه نیز ارائه شده است. بنده این کلاس را کپی کرده و تمامی ترجمههای آنها را نیز نوشتم ( اگر در ترجمه ایرادی بود به بزرگی خودتان بخشیده و تصحیح نمائید . ) که کد آن را در زیر میتوانید در اختیار داشته باشید:
class PersianRadGridLocalizationProvider : RadGridLocalizationProvider { public override string GetLocalizedString(string id) { switch (id) { case RadGridStringId.FilterFunctionBetween: return "بین"; //Between case RadGridStringId.FilterOperatorBetween: return "بین"; case RadGridStringId.FilterFunctionContains: return "حاوی"; case RadGridStringId.FilterOperatorContains: return "حاوی"; case RadGridStringId.FilterFunctionDoesNotContain: return "شامل نشود"; //Does not contain case RadGridStringId.FilterOperatorDoesNotContain: return "شامل نشود"; case RadGridStringId.FilterFunctionEndsWith: return "پایان پذیرد با"; //Ends with case RadGridStringId.FilterOperatorEndsWith: return "پایان پذیرد با"; case RadGridStringId.FilterFunctionEqualTo: return "برابر با"; //Equals case RadGridStringId.FilterOperatorEqualTo: return "برابر با"; case RadGridStringId.FilterFunctionGreaterThan: return "بزرگتر از"; //Greater than case RadGridStringId.FilterOperatorGreaterThan: return "بزرگتر از"; case RadGridStringId.FilterFunctionGreaterThanOrEqualTo: return "بزرگتر یا مساوی با"; //Greater than or equal to case RadGridStringId.FilterOperatorGreaterThanOrEqualTo: return "بزرگتر یا مساوی با"; case RadGridStringId.FilterFunctionIsEmpty: return "خالی باشد"; //Is empty case RadGridStringId.FilterOperatorIsEmpty: return "خالی باشد"; case RadGridStringId.FilterFunctionIsNull: return "تهی باشد"; //Is null case RadGridStringId.FilterOperatorIsNull: return "تهی باشد"; case RadGridStringId.FilterFunctionLessThan: return "کمتر از"; //Less than case RadGridStringId.FilterOperatorLessThan: return "کمتر از"; case RadGridStringId.FilterFunctionLessThanOrEqualTo: return "کمتر یا مساوی با"; //Less than or equal to case RadGridStringId.FilterOperatorLessThanOrEqualTo: return "کمتر یا مساوی با"; case RadGridStringId.FilterFunctionNoFilter: return "بدون شرط"; //No filter case RadGridStringId.FilterOperatorNoFilter: return "بدون شرط"; case RadGridStringId.FilterFunctionNotBetween: return "نباشد بین"; //Not between case RadGridStringId.FilterOperatorNotBetween: return "نباشد بین"; //Operator case RadGridStringId.FilterFunctionNotEqualTo: return "برابر نباشد با"; //Not equal to case RadGridStringId.FilterOperatorNotEqualTo: return "برابر نباشد با"; case RadGridStringId.FilterFunctionNotIsEmpty: return "خالی نباشد"; //Is not empty case RadGridStringId.FilterFunctionNotIsNull: return "خالی نباشد"; //Is not null case RadGridStringId.FilterFunctionStartsWith: return "شروع شود با"; //Starts with case RadGridStringId.FilterFunctionCustom: return "شرط دلخواه"; //Custom case RadGridStringId.CustomFilterMenuItem: return "شرط دلخواه منو"; //Custom case RadGridStringId.CustomFilterDialogCaption: return "انتخاب شرط دلخواه"; //RadGridView Custom Filter Dialog case RadGridStringId.CustomFilterDialogLabel: return ":نشان دادن سطرهایی که"; //Show rows where: case RadGridStringId.CustomFilterDialogRbAnd: return "و"; //And case RadGridStringId.CustomFilterDialogRbOr: return "یا"; //Or case RadGridStringId.CustomFilterDialogBtnOk: return "تایید"; //OK case RadGridStringId.CustomFilterDialogBtnCancel: return "انصراف"; //Cancel case RadGridStringId.AddNewRowString: return "برای افزودن سطر جدید اینجا کلیک کنید"; case RadGridStringId.ClearValueMenuItem: return "پاک کردن مقدار سلول"; case RadGridStringId.DeleteRowMenuItem: return "حذف سطر"; //Delete Row case RadGridStringId.SortAscendingMenuItem: return "مرتب سازی صعودی"; //Sort Ascending case RadGridStringId.SortDescendingMenuItem: return "مرتب سازی نزولی"; //Sort Descending case RadGridStringId.ClearSortingMenuItem: return "حذف مرتب سازی"; //Clear Sorting case RadGridStringId.ConditionalFormattingMenuItem: return "قالب بندی مشروط"; //Conditional Formatting case RadGridStringId.GroupByThisColumnMenuItem: return "گروهبندی بر حسب این ستون"; //Group by this column case RadGridStringId.UngroupThisColumn: return "حذف این ستون از گروهبندی "; //Ungroup this column case RadGridStringId.ColumnChooserMenuItem: return "انتخابگر ستون"; //Column Chooser case RadGridStringId.HideMenuItem: return "مخفی کردن ستون"; //Hide case RadGridStringId.UnpinMenuItem: return "حالت پیش فرض"; //Unpin case RadGridStringId.PinMenuItem: return "حالت ستون"; //Pin case RadGridStringId.PinAtLeftMenuItem: return "چسپیدن به سمت چپ"; case RadGridStringId.PinAtRightMenuItem: return "چسپیدن به سمت راست"; case RadGridStringId.PinAtTopMenuItem: return "چسپیدن به بالا"; case RadGridStringId.PinAtBottomMenuItem: return "چسپیدن به پایین"; case RadGridStringId.BestFitMenuItem: return "اندازه بهینه ستون"; //Best Fit case RadGridStringId.PasteMenuItem: return "چسپاندن"; //Paste case RadGridStringId.EditMenuItem: return "ویرایش"; //Edit case RadGridStringId.CopyMenuItem: return "کپی"; //Copy case RadGridStringId.ConditionalFormattingCaption: return "قالب بندی مشروط"; //Custom Formatting Condition Editor case RadGridStringId.ConditionalFormattingLblColumn: return "قالب بندی سلولهایی با شرط:"; //Column: case RadGridStringId.ConditionalFormattingLblName: return "نام شرط:"; //Name: case RadGridStringId.ConditionalFormattingLblType: return "مقدار سلول:"; //Type: case RadGridStringId.ConditionalFormattingLblValue1: return "مقدار اول:"; //Value 1: case RadGridStringId.ConditionalFormattingLblValue2: return "مقدار دوم:"; //Value 2: case RadGridStringId.ConditionalFormattingGrpConditions: return "شرایط"; //Conditions case RadGridStringId.ConditionalFormattingGrpProperties: return "مشخصات"; //Properties case RadGridStringId.ConditionalFormattingChkApplyToRow: return "اعمال این شرط به کل سطر"; //Apply to row case RadGridStringId.ConditionalFormattingBtnAdd: return "افزودن شرایط"; //Add case RadGridStringId.ConditionalFormattingBtnRemove: return "حذف شرایط انتخابی"; //Remove case RadGridStringId.ConditionalFormattingBtnOK: return "تایید"; //OK case RadGridStringId.ConditionalFormattingBtnCancel: return "انصراف"; //Cancel case RadGridStringId.ConditionalFormattingBtnApply: return "اعمال قالب بندی"; //Apply case RadGridStringId.ColumnChooserFormCaption: return "انتخاب ستون ها"; //Column Chooser case RadGridStringId.ColumnChooserFormMessage: return "برای حذف یکی از ستونها، آن ستون را به اینجا بکشید";//"Drag a column header from the grid here to remove it from the current view."; case RadGridStringId.CompositeFilterFormErrorCaption: return "خطا"; case RadGridStringId.ConditionalFormattingChooseOne: return "[یکی را انتخاب کنید]"; case RadGridStringId.ConditionalFormattingContains: return "[حاوی [مقدار اول"; case RadGridStringId.ConditionalFormattingDoesNotContain: return "حاوی [مقدار اول] نباشد"; case RadGridStringId.ConditionalFormattingEndsWith: return "با [مقدار اول] پایان یابد"; case RadGridStringId.ConditionalFormattingEqualsTo: return "[برابر با [مقدار اول"; case RadGridStringId.ConditionalFormattingIsBetween: return "بین [مقدار اول] و [مقدار دوم] باشد"; case RadGridStringId.ConditionalFormattingIsGreaterThan: return "[بزرگتر از [مقدار اول"; case RadGridStringId.ConditionalFormattingIsGreaterThanOrEqual: return "[بزرگتر یا مساوی با [مقدار اول"; case RadGridStringId.ConditionalFormattingIsLessThan: return "کوچکتر از [مقدار اول]"; case RadGridStringId.ConditionalFormattingIsLessThanOrEqual: return "کوچکتر یا مساوی با [مقدار اول]"; case RadGridStringId.ConditionalFormattingIsNotBetween: return "بین [مقدار اول] و [مقدار دوم] نباشد"; case RadGridStringId.ConditionalFormattingIsNotEqualTo: return "برابر با [مقدار اول] نباشد"; case RadGridStringId.ConditionalFormattingRuleAppliesOn: return "اعمال شرایط روی:"; case RadGridStringId.ConditionalFormattingStartsWith: return "با [مقدار اول] شروع میشود"; case RadGridStringId.CustomFilterDialogCheckBoxNot: return "با این شرایط نباشد"; case RadGridStringId.CustomFilterDialogFalse: return "False"; case RadGridStringId.CustomFilterDialogTrue: return "True"; case RadGridStringId.FilterCompositeNotOperator: return "نباشد"; case RadGridStringId.FilterLogicalOperatorAnd: return "و"; case RadGridStringId.FilterLogicalOperatorOr: return "یا"; case RadGridStringId.FilterMenuAvailableFilters: return "فیلتر شده"; case RadGridStringId.FilterMenuButtonCancel: return "انصراف"; case RadGridStringId.FilterMenuButtonOK: return "تایید"; case RadGridStringId.FilterMenuClearFilters: return "پاک کردن فیلتر"; case RadGridStringId.FilterMenuSearchBoxText: return "جستجو..."; case RadGridStringId.FilterMenuSelectionAll: return "همه"; //case RadGridStringId.FilterMenuSelectionAllSearched: return "نتیجه همه جستجو"; case RadGridStringId.FilterMenuSelectionNotNull: return "خالی نباشد"; case RadGridStringId.FilterMenuSelectionNull: return "خالی باشد"; case RadGridStringId.FilterOperatorCustom: return "دلخواه"; case RadGridStringId.FilterOperatorIsLike: return "مانند"; case RadGridStringId.FilterOperatorNotIsContainedIn: return "نباشد در"; case RadGridStringId.FilterOperatorNotIsEmpty: return "خالی نباشد"; case RadGridStringId.FilterOperatorNotIsLike: return "نباشد شبیه"; case RadGridStringId.FilterOperatorNotIsNull: return "خالی نباشد"; case RadGridStringId.FilterOperatorStartsWith: return "شروع شود با"; case RadGridStringId.GroupingPanelDefaultMessage: return "برای گروهبندی ستونها، ستونی را به اینجا بکشید"; case RadGridStringId.GroupingPanelHeader: return ":گروهبندی بر حسب"; case RadGridStringId.NoDataText: return "داده ای برای نمایش وجود ندارد"; case RadGridStringId.UnpinRowMenuItem: return "حالت پیش فرض"; default: return base.GetLocalizedString(id); } } }
7 - حال اگر برنامه را اجرا کنید باز موارد انگلیسی گرید تلریک فارسی نمیشوند و باید در کلاس Program.cs پروژه این یک خط کد را هم اضافه نمائید.
//using Telerik.WinControls.UI.Localization; RadGridLocalizationProvider.CurrentProvider = new PersianRadGridLocalizationProvider();
8 - حال اگر برنامه را اجرا نمایید تمامی موارد را فارسی مشاهده خواهید نمود ( شکل ذیل )
لطفا ما را از نظرات سازنده خود بی نصیب نفرمائید. با تشکر
- آشنایی با Angular CLI
- آشنایی با مسیریابیها در Angular
همچنین اگر پیشتر Angular CLI را نصب کردهاید، قسمت «به روز رسانی Angular CLI» ذکر شدهی در مطلب «Angular CLI - قسمت اول - نصب و راه اندازی» را نیز اعمال کنید. در این سری از angular/cli: 1.1.2@ استفاده شدهاست.
فناوریهای مختلف کار با فرمها در Angular
Angular (که خلاصه شدهی نام تمام نگارشهای پس از Angular 2 است)، به همراه دو فناوری توکار کار با فرمها است:
الف) فرمهای مبتنی بر قالبها یا Template driven forms
در اینجا عمدهی کار تعاریف فرمها، در قالبهای HTML ایی کامپوننتها به همراه data binding انجام میشود. کار با آن سادهتر است و به همراه حداقل کدنویسی در قسمت کامپوننتهای برنامه است؛ چون two-way data binding بسیاری از مسایل را به صورت خودکار مدیریت میکند. همچنین این روش برای کسانیکه با Angular 1.x کار کرده باشند، آشناتر است.
ب) فرمهای واکنشی یا Reactive forms
در اینجا نیز همانند حالت الف کار تعریف ابتدایی فرم در قالبهای HTML ایی کامپوننتها انجام میشود. اما در اینجا نیاز است مدل فرم را توسط کدهای TypeScript کامپوننت نیز ایجاد کرد و با قالب HTML ایی هماهنگ نمود (به همین جهت به آن model driven forms هم میگویند). مزیت این روش نسبت به حالت الف، سادگی Unit testing و همچنین امکان تعریف اعتبارسنجیهای پیچیدهاست. به علاوه در این حالت میتوان فرمهای پویایی را نیز طراحی کرد.
ما در این سری حالت Template driven forms را بررسی خواهیم کرد.
ایجاد ساختار اولیهی مثال این سری
در ادامه، یک پروژهی جدید مبتنی بر Angular CLI را به نام angular-template-driven-forms-lab به همراه تنظیمات ابتدایی مسیریابی آن ایجاد میکنیم:
> ng new angular-template-driven-forms-lab --routing
> npm install bootstrap --save
"apps": [ { "styles": [ "../node_modules/bootstrap/dist/css/bootstrap.min.css", "styles.css" ],
در ادامه برای تکمیل مثال جاری، دو کامپوننت جدید خوشآمدگویی و همچنین یافتن نشدن مسیرها را به برنامه اضافه میکنیم:
>ng g c welcome >ng g c PageNotFound
@NgModule({ declarations: [ AppComponent, WelcomeComponent, PageNotFoundComponent ],
سپس فایل src\app\app-routing.module.ts را به نحو ذیل تکمیل نمائید:
import { PageNotFoundComponent } from './page-not-found/page-not-found.component'; import { WelcomeComponent } from './welcome/welcome.component'; import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = [ { path: 'welcome', component: WelcomeComponent }, { path: '', redirectTo: 'welcome', pathMatch: 'full' }, { path: '**', component: PageNotFoundComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
همچنین مدیریت مسیریابی آدرسهای ناموجود در سایت نیز با تعریف ** صورت گرفتهاست.
زمانیکه یک کامپوننت فعالسازی میشود، قالب آن در router-outlet نمایش داده خواهد شد. برای این منظور فایل src\app\app.component.html را گشوده و به نحو ذیل تغییر دهید:
<nav class="navbar navbar-default"> <div class="container-fluid"> <a class="navbar-brand">{{title}}</a> <ul class="nav navbar-nav"> <li> <a [routerLink]="['/']">Home</a> </li> </ul> </div> </nav> <div class="container"> <router-outlet></router-outlet> </div>
افزودن ماژول فرمها به برنامه
پس از ایجاد ساختار اولیه برنامه، اولین کاری را که در جهت استفادهی از فرمهای مبتنی بر قالبها باید انجام داد، افزودن ماژول فرمها به ماژول اصلی برنامه است. برای این منظور فایل src\app\app.module.ts را گشوده و تغییرات ذیل را به آن اعمال کنید:
import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ BrowserModule, FormsModule, AppRoutingModule ]
ایجاد ماژول و کامپوننت فرم ثبت نام کارمندان
در ادامه میخواهیم فرم ثبت نام یک کارمند را تکمیل کنیم. بنابراین ماژول جدید کارمندان را به همراه تنظیمات ابتدایی مسیریابی آن ایجاد میکنیم:
>ng g m Employee -m app.module --routing
installing module create src\app\employee\employee-routing.module.ts create src\app\employee\employee.module.ts update src\app\app.module.ts
import { EmployeeRoutingModule } from './employee/employee-routing.module'; @NgModule({ imports: [ BrowserModule, FormsModule, AppRoutingModule, EmployeeRoutingModule ]
همچنین برای اینکه کامپوننتهای این ماژول نیز در حین مسیریابی در دسترس باشند، نیاز است بجای EmployeeRoutingModule، خود EmployeeModule را ذکر کرد که حاوی تعاریف مسیریابی (ذکر EmployeeRoutingModule در قسمت imports آن) نیز میباشد. بنابراین فایل app.module.ts چنین تعاریفی را پیدا میکند:
import { EmployeeModule } from './employee/employee.module'; @NgModule({ imports: [ BrowserModule, FormsModule, EmployeeModule, AppRoutingModule ]
در ادامه کامپوننت جدید ثبت یک کارمند را به این ماژول اضافه میکنیم:
>ng g c employee/employee-register
installing component create src\app\employee\employee-register\employee-register.component.css create src\app\employee\employee-register\employee-register.component.html create src\app\employee\employee-register\employee-register.component.spec.ts create src\app\employee\employee-register\employee-register.component.ts update src\app\employee\employee.module.ts
import { EmployeeRegisterComponent } from './employee-register/employee-register.component'; @NgModule({ declarations: [EmployeeRegisterComponent]
در ادامه میخواهیم قالب این کامپوننت را در منوی اصلی سایت قابل دسترسی کنیم. به همین جهت به فایل src\app\employee\employee-routing.module.ts مراجعه کرده و مسیریابی این کامپوننت را تعریف میکنیم:
import { EmployeeRegisterComponent } from './employee-register/employee-register.component'; const routes: Routes = [ { path: 'register', component: EmployeeRegisterComponent } ];
سپس میخواهیم لینکی را به این مسیریابی جدید اضافه کنیم. به همین جهت به فایل src\app\app.component.html مراجعه کرده و routerLink آنرا اضافه میکنیم:
<ul class="nav navbar-nav"> <li> <a [routerLink]="['/']">Home</a> </li> <li> <a [routerLink]="['/register']">Register</a> </li> </ul>
در قسمت بعد، ایجاد اولین فرم مبتنی بر قالبها را پیگیری میکنیم.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: angular-template-driven-forms-lab-01.zip
برای اجرای آن فرض بر این است که پیشتر Angular CLI را نصب کردهاید. سپس از طریق خط فرمان به ریشهی پروژه وارد شده و دستور npm install را صادر کنید تا وابستگیهای آن دریافت و نصب شوند. در آخر با اجرای دستور ng serve -o برنامه ساخته شده و در مرورگر پیش فرض سیستم نمایش داده خواهد شد.
جهت رای دادن به این ویژگی اقدام فرمایید.
هچنین میتوان از راه زیر چنین ویژگی را نیز فعال کرد: (محتوای فایل LaunchSettings.json)
"profiles": { "Watch": { "commandName": "Executable", "executablePath": "dotnet", "workingDirectory": "$(ProjectDir)", "hotReloadEnabled": true, "hotReloadProfile": "aspnetcore", "commandLineArgs": "watch run", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } }
ASP.NET MVC #23
C:\Windows\System32\inetsrv\config\applicationHost.config
جدول خصوصیت ها
خصوصیت | توضیح |
customLogPluginClsid | یک پارامتر رشتهای اختیاری که در آن، آی دی کلاس یا کلاسهایی نوشته میشود که برای custom logging نوشته شدهاند و این گزینه ترتیب اجرای آنها را تعیین میکند. |
directory | اختیاری است. محل ذخیرهی لاگ فایلها را مشخص میکند و در صورتیکه ذکر نشود، همان مسیر پیش فرض است. |
enabled | اختیاری است. فعال بودن سیستم لاگ برای آن سایت را مشخص میکند. مقدار پیش فرض آن true است. |
flushByEntryCountW3CLog | این مقدار مشخص میکند چند رخداد باید اتفاق بیفتد تا عمل ذخیره سازی لاگ صورت گیرد. اگر بعد از هر رخداد عمل ثبت لاگ انجام شود، سرعت ثبت لاگها بالا میرود؛ ولی باعث استفادهی مداوم از منابع و همچنین درخواست ثبت اطلاعات را روی دیسک خواهد داد و تاوان آن با زیاد شدن عملیات روی دیسک، پرداخته خواهد شد. ولی در حالتیکه چند رخداد را نگهداری سپس دستهای ثبت کند، باعث افزایش کارآیی و راندمان سرور خواهد شد. در صورتیکه سرور به مشکلات لحظهای برخورد میکند مقدار آن را کاهش دهید. مقدار پیش فرض 0 است. یعنی اینکه ثبت، بعد از 64000 لاگ خواهد بود. |
localTimeRollover | نحوهی نامگذاری فایلهای لاگ را مشخص میکند که مقدار بولین گرفته و اختیاری است. به طور پیش فرض مقدار false دارد. |
logExtFileFlags | این گزینه در حالتی به کارتان میآید که فرمت W3C را برای ثبت لاگها انتخاب کرده باشید و در اینجا مشخص میکنید که چه فیلدهایی باید در لاگ باشند و اگر بیش از یکی بود میتوان با ، (کاما) از هم جدایشان کرد. |
logFormat | نوع فرمت ذخیره سازی لاگها |
logSiteId | اختیاری است و مقدار پیش فرض آن true است. بدین معنا که کد یا شمارهی سایت هم در لاگ خواهد بود و این در حالتی است که گزارش در سطح سرور باشد. در غیر این صورت اگر هر سایت، جداگانه لاگی برای خود داشته باشد، ذکر نمیگردد. |
logTargetW3C | اختیاری است و و مقدار file و *ETW را میگیرد که به طور پیش فرض روی File تنظیم است. در این حالت فایل لاگها در یک فایل متنی توسط http.sys ذخیره میشود. ولی موقعیکه از ETW استفاده میشود، http.sys با استفاده از iislogprovider دادهها را به سمت ETW ارسال میکند که منجر به اجرای سرویس Logsvc شده که از دادهها کوئری گرفته و آنها را مستقیما از پروسههای کارگر جمع آوری و به سمت فایل لاگ ارسال میکند. همچنین انتخاب این دو گزینه نیز ممکن است. |
maxLogLineLength | حداکثر تعداد خطی که یک لاگ میتواند داشته باشد تا اینکه بتوانید در مصرف دیسک سخت صرفه جویی کنید و بیشتر کاربرد آن برای لاگهای کاستوم است. این عدد باید از نوع Uint باشد و اختیاری است و از 2 تا 65536 مقدار میپذیرد که مقدار پیش فرض آن 65536 میباشد. |
period | همان مبحث زمان بندی در مورد ایجاد فایلهای لاگ است که در مقالهی پیشین برسی کردیم و مقادیر Dialy,Hourly,monthlyو weekly را میپذیرد. همچنین maxsize هم هست؛ موقعی که لاگ به نهایت حجمی که برای آن تعیین کردیم میرسد. |
truncateSize | اختیاری است و مقدار آن از نوع int64 است. حداکثر حجم یک فایل لاگ را مشخص میکند تا اگر period روی maxsize تنظیم شده بود، حداکثر حجم را میتوان از اینجا تعیین نمود. در مقاله پیشین در این باره صحبت کردیم؛ حداقل عدد برای آن 1,048,576 است و اگر کمتر از آن بنویسید، سیستم همین عدد 1,048,576 را در نظر خواهد گرفت. مقدار پیش فرض آن 20971520 می باشد. |
<system.applicationHost> <sites> <siteDefaults> <logFile logFormat="W3C" directory="%SystemDrive%\inetpub\logs\LogFiles" enabled="true"> <customFields> <clear/> <add logFieldName="ContosoField" sourceName="ContosoSource" sourceType="ServerVariable" /> </customFields> </logFile> </siteDefaults> </sites> </system.applicationHost>
تغییر تنظمیات لاگ با Appcmd
appcmd.exe set config -section:system.applicationHost/sites /siteDefaults.logFile.enabled:"True" /commit:apphost appcmd.exe set config -section:system.applicationHost/sites /siteDefaults.logFile.logFormat:"W3C" /commit:apphost appcmd.exe set config -section:system.applicationHost/sites /siteDefaults.logFile.directory:"%SystemDrive%\inetpub\logs\LogFiles" /commit:apphost
تنظمیات تگ لاگ با برنامه نویسی و اسکریپت نویسی
using System; using System.Text; using Microsoft.Web.Administration; internal static class Sample { private static void Main() { using (ServerManager serverManager = new ServerManager()) { Configuration config = serverManager.GetApplicationHostConfiguration(); ConfigurationSection sitesSection = config.GetSection("system.applicationHost/sites"); ConfigurationElement siteDefaultsElement = sitesSection.GetChildElement("siteDefaults"); ConfigurationElement logFileElement = siteDefaultsElement.GetChildElement("logFile"); logFileElement["logFormat"] = @"W3C"; logFileElement["directory"] = @"%SystemDrive%\inetpub\logs\LogFiles"; logFileElement["enabled"] = true; serverManager.CommitChanges(); } } }
با استفاده از اسکریپت نویسی توسط جاوااسکریپت و وی بی اسکریپت هم نیز این امکان مهیاست:
var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager'); adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST"; var sitesSection = adminManager.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST"); var siteDefaultsElement = sitesSection.ChildElements.Item("siteDefaults"); var logFileElement = siteDefaultsElement.ChildElements.Item("logFile"); logFileElement.Properties.Item("logFormat").Value = "W3C"; logFileElement.Properties.Item("directory").Value = "%SystemDrive%\\inetpub\\logs\\LogFiles"; logFileElement.Properties.Item("enabled").Value = true; adminManager.CommitChanges();
FTP Logging
IIS را باز کنید و در لیست درختی، سرور را انتخاب کنید. در قسمت FTP میتوانید گزینهی Ftp logging را ببینید. تنظیمات این قسمت هم دقیقا همانند قسمت logging میباشد و همان موارد برای آن هم صدق میکند.
بررسی تگ آن در applicationhost
تگ این نوع لاگ در فایل applicationhost در زیر مجموعهی تگ <site> به شکل زیر نوشته میشود:
<system.ftpServer> <log centralLogFileMode="Central"> <centralLogFile enabled="true" /> </log> </system.ftpServer>
گزینه centralLogFileMode دو مقدار central و site را میپذیرد. اگر گزینهی central انتخاب شود، یعنی همهی لاگها را داخل یک فایل در سطح سرور ثبت کن ولی اگر گزینهی site انتخاب شده باشد، لاگ هر سایت در یک فایل ثبت خواهد شد.
گزینهی logInUTF8 یک خصوصیت اختیاری است که مقدار پیش فرض آن true میباشد. در این حالت باید تمامی رشتهها به انکدینگ UTF-8 تبدیل شوند.
همانطور که میبینید تگ log در بالا یک تگ فرزند هم به اسم centralLogFile دارد که همان خصوصیات جدول بالا در آن مهیاست.
دسترسی به تنظیمات این قسمت توسط دستور Appcmd:
appcmd.exe set config -section:system.ftpServer/log /centralLogFileMode:"Central" /commit:apphost appcmd.exe set config -section:system.ftpServer/log /centralLogFile.enabled:"True" /commit:apphost
دسترسی به تنظیمات این قسمت توسط دات نت:
using System; using System.Text; using Microsoft.Web.Administration; internal static class Sample { private static void Main() { using (ServerManager serverManager = new ServerManager()) { Configuration config = serverManager.GetApplicationHostConfiguration(); ConfigurationSection logSection = config.GetSection("system.ftpServer/log"); logSection["centralLogFileMode"] = @"Central"; ConfigurationElement centralLogFileElement = logSection.GetChildElement("centralLogFile"); centralLogFileElement["enabled"] = true; serverManager.CommitChanges(); } } }
دسترسی به تنظیمات این قسمت توسط Javascript:
var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager'); adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST"; var logSection = adminManager.GetAdminSection("system.ftpServer/log", "MACHINE/WEBROOT/APPHOST"); logSection.Properties.Item("centralLogFileMode").Value = "Central"; var centralLogFileElement = logSection.ChildElements.Item("centralLogFile"); centralLogFileElement.Properties.Item("enabled").Value = true; adminManager.CommitChanges();
<script> let src = 'https://svelte.dev/tutorial/image.gif'; let name = 'Rick Astley'; </script> <img src={src} alt="{name} dancing">
- نکته اول : اگر در تگ img مقدار alt را وارد نکنیم و یا alt در این تگ وجود نداشته باشد، یک هشدار توسط کامپایلر svelte برای ما با عنوان <img> element should have an alt attribute> ایجاد میشود. زمان ساخت یک برنامه بسیار مهم است تا قوانین نوشتن یک کد html خوب را رعایت کنیم تا برای تمامی کاربران احتمالی برنامه قابل استفاده باشد. در همین مثال با ایجاد یک هشدار Svelte تلاش میکند که ما را از اشتباه در نوشتن کد html مطلع سازد.
- نکته دوم : اگر نام یک آبجکت تعریف شده و یک attribute، برابر باشد میتوانیم از نسخه کوتاه شده یا Shorthand attributes در svelte استفاده کنیم. به طور مثال در مثال بالا میتوانیم از کد زیر در خط 6 استفاده کنیم.
<img {src} alt="{name} dancing">
<script> export let siteName = "dotnettips"; </script> <p>this is a nested component for third tutorial on {siteName}</p>
<script> import Nested from "./Nested.svelte"; export let name; </script> <h1>Hello {name}!</h1> <Nested siteName="dotnettips.info" />
Hello world! this is a nested component for third tutorial on dotnettips.info
در مثال بالا ما یک کامپوننت جدید را ایجاد کرده و از طریق دستور import به App.svelte اضافه کردیم. نکتهای که در اینجا وجود دارد، نحوه مقدار دهی props در کامپوننتها است. اگر به خط 9 دقت کنیم، کامپوننت ما از طریق تگ جدیدی با نام (Nested) به بدنه html برنامه اضافه شده است که یک attribute به نام siteName دارد. siteName متغیر export شده در کامپوننت Nested.svelte است که در کامپوننتها به این صورت مقدار دهی میشود. قبلا نحوه مقدار دهی این خصیصهها را در فایلهای جاوا اسکریپت مشاهده کرده بودیم. نکته دیگری که باید به آن دقت داشت این است که خصیصه siteName مقدار پیش فرض dotnettips را در Nested.svelte به خود اختصاص داده بود. به همین جهت اگر ما siteName را هنگام استفاده از کامپوننت مقدار دهی نکنیم، از مقدار پیش فرض خود استفاده خواهد کرد. ولی اینجا ما با مقدار دهی آن، siteName را به dotnettips.info تغییر دادهایم.
نکته مهم : دقت داشته باشید کامپوننتهای شما همیشه باید با حروف بزرگ شروع شوند؛ به طور مثال در صورت نوشتن <nested/> محتوای کامپوننت نمایش داده نخواهد شد. svelte، از طریق زیر نظر گرفتن حروف کوچک و بزرگ در ابتدای تگها، بین تگهای html و کامپوننتها تمایز قائل میشود.
Spread props :
تا اینجا به صورت خلاصه با props یا خصیصهها آشنا شدهاید و دیدیم که با export کردن یک متغیر در یک کامپوننت، میتوانیم آن را هنگام استفاده مقدار دهی نماییم. برای اینکه تمرینی هم باشد با توجه به مطالبی که تاکنون گفته شده، پروژهی جدیدی را ایجاد کنید و محتوای App.svelte را مانند کد زیر تغییر دهید.
<script> import Info from './Info.svelte'; const pkg = { name: 'svelte', version: 3, speed: 'blazing', website: 'https://svelte.dev' }; </script> <Info name={pkg.name} version={pkg.version} speed={pkg.speed} website={pkg.website}/>
همانطور که در خط دوم کد میبینید، کامپوننتی به نام Info.svelte به این بخش اضافه شدهاست. این کامپوننت را با محتوای زیر ایجاد نمایید:
<script> export let name; export let version; export let speed; export let website; </script> <p> The <code>{name}</code> package is {speed} fast. Download version {version} from <a href="https://www.npmjs.com/package/{name}">npm</a> and <a href={website}>learn more here</a> </p>
اگر برنامه را اجرا کنید یک چنین خروجی را مشاهده خواهید کرد:
The svelte package is blazing fast. Download version 3 from npm and learn more here
<Info {...pkg}/>
<script> let count = 0; function handleClick() { count += 1; } </script> <p>Count : {count}</p> <button on:click={handleClick}> Clicked {count} {count === 1 ? 'time' : 'times'} </button>
<script> let count = 0; let doubled = count * 2; function handleClick() { count += 1; } </script> <button on:click={handleClick}> Clicked {count} {count === 1 ? 'time' : 'times'} </button> <p>{count} doubled is {doubled}</p>
$: doubled = count * 2;
$: console.log(`the count is ${count}`);
$: { console.log(`the count is ${count}`); alert(`I SAID THE COUNT IS ${count}`); }
$: if (count >= 10) { alert(`count is dangerously high!`); count = 9; }
<script> let numbers = [1, 2, 3, 4]; function addNumber() { let newNumber = numbers.length + 1; numbers.push(newNumber); } $: sum = numbers.reduce((t, n) => t + n, 0); </script> <p>{numbers.join(' + ')} = {sum}</p> <button on:click={addNumber}>Add a number</button>
function addNumber() { let newNumber = numbers.length + 1; numbers.push(newNumber); numbers = numbers; }
function addNumber() { let newNumber = numbers.length + 1; numbers = [...numbers, newNumber]; }
مروری بر Two way bindings :
<script> let name = ""; function updateName(event) { name = event.target.value; } </script> <h4>My Name Is {name}</h4> <input value={name} on:input={updateName} />
<script> let name = ""; </script> <h4>My Name Is {name}</h4> <input bind:value={name} />
{#if condition} <!-- you html codes ... --> {/if}
<script> let user = { loggedIn: false }; function toggle() { user.loggedIn = !user.loggedIn; } </script> {#if user.loggedIn} <button on:click={toggle}> Log out </button> {/if} {#if !user.loggedIn} <button on:click={toggle}> Log in </button> {/if}
{#if condition} <!-- you html code when condition is true --> {:else} <!-- you html code when condition is false --> {/if}
{#if user.loggedIn} <button on:click={toggle}> Log out </button> {:else} <button on:click={toggle}> Log in </button> {/if}
{#if condition} <!-- you html code when condition is true --> {:else if condition2} <!-- you html code when condition2 is true --> {:else} <!-- you html code when condition and condition2 are false --> {/if}
{#each list as item} <!-- you html code per each item in list --> {/each}
<script> let cats = [ { id: 'J---aiyznGQ', name: 'Keyboard Cat' }, { id: 'z_AbfPXTKms', name: 'Maru' }, { id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' } ]; </script> <h1>The Famous Cats of YouTube</h1> <ul> {#each cats as cat} <li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}"> {cat.name} </a></li> {/each} </ul>
<ul> {#each cats as {id,name}} <li><a target="_blank" href="https://www.youtube.com/watch?v={id}"> {name} </a></li> {/each} </ul>
<ul> {#each cats as { id, name }, i} <li><a target="_blank" href="https://www.youtube.com/watch?v={id}"> {i + 1}: {name} </a></li> {/each} </ul>
نکته : در این بخش من سعی کردم تا حدودی به ترتیب بخش آموزشی خود وبسایت Svelte، موارد را بیان کنم؛ ولی با توجه به اینکه شاید دوستان ترجیح بدهند روش آموزشی خود آن وبسایت که امکان تغییر و نوشتن کد را هم محیا کرده است، امتحان کنند لینک آن را به اشتراک میگذارم.
DECLARE @Test TABLE ( RowID INT IDENTITY, FName VARCHAR(20), Salary SMALLINT ); INSERT INTO @Test (FName, Salary) VALUES ('George', 800), ('Sam', 950), ('Diane', 1100), ('Nicholas', 1250), ('Samuel', 1250), ('Patricia', 1300), ('Brian', 3000), ('Thomas', 1600), ('Fran', 2450), ('Debbie', 2850), ('Mark', 2975), ('James', 3000), ('Cynthia', 3000), ('Christopher', 5000); SELECT RowID,FName,Salary, SumByRows = SUM(Salary) OVER (ORDER BY Salary ROWS UNBOUNDED PRECEDING), SumByRange = SUM(Salary) OVER (ORDER BY Salary RANGE UNBOUNDED PRECEDING) FROM @Test ORDER BY RowID;
نکاتی در باب T-SQL
Create Table Test(ID int,Firstname varchar(20)); Insert Into Test (ID,Firstname) Values(1,'K'); Insert Into Test (ID,Firstname) Values(2,'B'); Insert Into Test (ID) Values(3);
Select COUNT(*) From Test
Select COUNT(Firstname) From Test
- هرگاه در اجرای Count ،هدفتان بدست آوردن تعداد ستون خاصی است، از (Count(column استفاده نمایید.
select count(cast(null as int)) select count(*) where 'a'='b' select € select ¥ select £ Select $ select count(*)-count(*) select Ascii('A')-Ascii('A') select LEN('')
- روش اول
(a+b)+ABS(a-b)
0.5(a+b)+ABS(a-b)
DECLARE @Value1 DECIMAL(5,2) = 80.22 DECLARE @Value2 DECIMAL(5,2) =90.34 SELECT (0.5 * ((@Value1 + @Value2) + ABS(@Value1 - @Value2))) AS MaxColumn
- روش دوم
DECLARE @Value1 DECIMAL(5,2) = 9.22 DECLARE @Value2 DECIMAL(5,2) = 8.34 SELECT CASE WHEN @Value1 > @Value2 THEN @Value1 ELSE @Value2 END AS MaxColumn
در این روش اگر مقدار یکی از اعداد Null باشد،ماکزیمم بین دو عدد، عدد غیر Null میباشد.
5- مشاهده مشخصات کلیه دیتابیسهای موجود در SQL Server با استفاده از Sys.Databases .
Select * From sys.databases
خروجی بصورت زیر خواهد بود:
6- بوسیله دستور OUTPUT میتوان خروجی Queryهای Delete،Update و Insert را مشاهده نمود:
مثال اول برای Query Delete :
در شکل، تک رکورد حذف شده را مشاهده مینمایید.
مثال دوم برای Query Update بصورت زیر میباشد:
در شکل، مقدار A، مقدار جدیدی است که بروز رسانی شده است و مقدار B مقداری است که مربوط به قبل از بروز رسانی میباشد.
مثال سوم برای Query Insert بصورت زیر میباشد:
موفق باشید.
Gulp #2
ساخت پروژه گالپ
npm init
name: (Gulp-RTLbootstrap-fontawesome) version: (1.0.0) description: An Awesome workflow entry point: (index.js) index.html test command: test git repository: https://github.com/mmdsharifi/gulp-rtlBootstrap-fontawesome.git keywords: gulp,rtlbootstrap,persian bootstrap author: Mohammad Sharifi license: (ISC) MIT
نصب گالپ
npm install gulp --save-dev
ایجاد فایل gulpfile.js
touch gulpfile.js
نوشتن اولین تسک گالپ
var gulp = require('gulp');
gulp.task('task-name', function() { // Stuff here });
gulp.task('hello', function() { console.log('Hello Gulp !'); });
البته که تسکهایی که برای گالپ مینویسیم، کاراتر از این است؛ برای مثال:
gulp.task('task-name', function () { return gulp.src('source-files') // Get source files with gulp.src .pipe(aGulpPlugin()) // Sends it through a gulp plugin .pipe(gulp.dest('destination')) // Outputs the file in the destination folder })
مخزن پروژه در گیت هاب : https://github.com/mmdsharifi/gulp-rtlBootstrap-fontawesome