وضعیت پشتیبانی از TLS 1.2 | نگارش دات نت |
پشتیبانی نمیشود. راه حلی هم ندارد. | NET 3.5. یا قبل از آن |
پشتیبانی نمیشود. اما اگر نگارش بالاتری نصب است، قطعه کد زیر را استفاده کنید:ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; | NET 4.0. |
پشتیبانی میشود، اما حالت پیشفرض نیست و باید دستی انتخاب شود:ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; | NET 4.5. |
حالت پیشفرض است و نیاز به تنظیمات خاصی ندارد. | NET 4.6. و یا بالاتر |
ساخت بستههای نیوگت مخصوص NET Core.
نکتهی آنرا در اینجا میتوانید مطالعه کنید و خلاصهی آن به صورت ذیل است:
"frameworks": { "net40": { "frameworkAssemblies": { } }, "net45": { "frameworkAssemblies": { } }, "net46": { "frameworkAssemblies": { } }, "netstandard1.3": { "imports": "dnxcore50", "dependencies": { "NETStandard.Library": "1.6.1", "System.Globalization.Extensions": "4.3.0", "System.Reflection": "4.3.0", "System.Reflection.TypeExtensions": "4.3.0" } } },
همین مقدار تغییر به همراه نکتهی scripts -> postcompile ابتدای بحث جاری، سبب خواهد شد تا کتابخانهی جاری برای تمام فریم ورکهای یاد شده به صورت مجزا کامپایل شده و درون بستهی نیوگت نهایی قرار گیرد:
در این حالت ممکن است قسمتی از کدها مثلا برای دات نت 4 قابل استفاده نباشند و نیاز به تغییر داشته باشند. برای این حالت باید از if directives# جهت شرطی کردن کامپایلر کمک گرفت:
#if NET40 // This only compiles for the .NET Framework 4 targets #else // This compiles for all other targets #endif
همچنین نگارش نهایی آن هم به زودی در دسترس خواهد بود.
+ زمانیکه قرار است از فریم ورکهای جاوا اسکریپتی SPA یا Single page applications مانند AngularJS استفاده شود، عملا دات نت تبدیل خواهد شد به فراهم کنندهی اطلاعات و دریافت کنندهی اطلاعات و نه بیشتر. بنابراین حداکثر به یک وب سرور نیاز خواهد بود؛ به همراه فناوری که بتواند JSON تولید کند (ارسال data به کلاینت) و JSON دریافت کند (دریافت data از کاربر). در این حالت اهمیتی ندارد که از MVC استفاده کنید یا از ASP.NET Web API و یا ... هر فناوری سمت سرور دیگری. همینقدر که این فناوری بتواند خروجی JSON را پردازش کند و یا در کنار آن وب سروری هم جهت هاست سایت فراهم باشد، کافی است.
یعنی در این حالت قابلیتهای رندر HTML فناوریهایی مانند ASP.NET MVC و هم ASP.NET Web forms فراموش خواهند شد؛ چون استفادهای از توانمندیهای آنها نخواهیم کرد.
استفاده از فریم ورکهای SPA یعنی آزادی انتخاب نحوهی ندر HTML نهایی و مدیریت فعالیتهای کاربران در سمت کاربر. سمت سرور آن هم چیزی بیشتر از دریافت و یا ارسال data با فرمت JSON نیست.
PHP سریعتر از ASP.NET! افسانه یا واقعیت؟
دنیای دات نت و مباحث مربوط به آن گستردهتر و پیچیدهتر از آن است که برای توجیه استفاده از دات نت سرعت مقایسه شود. دهها ویژگی منحصر به دات نت وجود دارد که برای انتخاب فناوری سمت سرور مجالی برای تفکر درباره سرعت باقی نمیگذارد و آنان که اهل تفکر باشند را جذب خود میکند و نه گمراهان (کسانی که یا تعصب دارند یا خستهتر از آن هستند که دنیای جدیدی را تجربه نمایند.)
در مورد سرعت کافی است نکات ساده ای که چند دقیقه بیشتر زمان نمیبرند رعایت شود تا وب سایتهای دات نتی چندین برابر سریعتر عمل کنند.
فراموش نکنید دنیای دات نت تا حد بیشتری با اصول مهندسی نرم افزار گره خورده است و باب میل همگان نیست.
عموماً سرویس دهنده بر حسب فناوری انتخاب میشود و نه برعکس! در مقالاتی که مقایسه انجام میدهند صحبت از رایگان بودن لینوکس و آپاچی و ... چندان ضرورتی ندارد.
بسیاری از آنها که Open Source بودن PHP را با آب و تاب و به عنوان برتری مطرح میکردند هرگز در عمر خود به کدهای سورس آن نگاهی نکرده اند. البته اگر بداند از کجا باید دانلود کنند. توصیه میکنم در مورد رویکرد و سیاستهای چند سال اخیر مایکروسافت در رابطه با Open Source تحقیق بیشتری صورت گیرد.
مثال هایی از سایتهای موفق و یا تعداد سایتها در یک فناوری هرگز دلیلی برای انتخاب فناوری نیست. ضمناً زمان ظهور این دو فناوری یکسان نبوده است که تعداد وب سایتها معیار مقایسه باشد.
فناوری-زبان PHP هنوز وجود دارد. هنوز قدرت خود را دارد. و هنوز هر کجا به هر دلیلی امکان استفاده از دات نت نبود، با کمال افتخار و خوشحالی از این که چند سال عمری که برای آن گذاشته ام هدر نرفته است به آن باز میگردم و آن را مورد استفاده قرار میدهم.
در این بین با توجه به اینکه دات نت پشتیبانی توکاری از SQL Server دارد، اتصال و استفاده از توانمندیهای آن نیاز به کتابخانه جانبی خاصی ندارد. اما برای کار با بانکهای اطلاعاتی دیگر نیاز خواهد بود تا پروایدر ADO.NET آنها را تهیه و به برنامه اضافه کنیم.
چهار نمونه از منابع داده پیش فرضی که در متد MainTableDataSource قابل تعریف هستند به شرح زیر میباشند:
public void SqlDataReader(string connectionString, string sql, params object[] parametersValues) //.mdb or .accdb files public void AccessDataReader(string filePath, string password, string sql, params object[] parametersValues) public void OdbcDataReader(string connectionString, string sql, params object[] parametersValues)
AccessDataReader قابلیت اتصال به بانکهای اطلاعاتی اکسس جدید (فایلهای accdb) و اکسس قدیم (فایلهای mdb) را دارد.
OdbcDataReader یک پروایدر عمومی است که از روز اول دات نت به همراه آن بوده است. برای مثال جهت اتصال به بانکهای اطلاعاتی فاکسپرو میتواند مورد استفاده قرار گیرد.
اما ... برای مابقی بانکهای اطلاعاتی چطور؟
برای سایر بانکهای اطلاعاتی، منبع داده عمومی زیر تدارک دیده شده است:
public void GenericDataReader(string providerName, string connectionString, string sql, params object[] parametersValues)
یک نکته:
در تمام منابع داده فوق، امکان نوشتن کوئریهای پارامتری نیز پیش بینی شده است. فقط باید دقت داشت که پارامترهای معرفی شده باید با @ شروع شوند که یک نمونه از آنرا در مثال جاری ملاحظه خواهید نمود.
در ادامه نحوه تهیه گزارش از یک بانک اطلاعاتی SQLite را توسط PdfReport بررسی خواهیم کرد:
using System; using PdfRpt.Core.Contracts; using PdfRpt.Core.Helper; using PdfRpt.FluentInterface; namespace PdfReportSamples.SQLiteDataReader { public class SQLiteDataReaderPdfReport { public IPdfReportData CreatePdfReport() { return new PdfReport().DocumentPreferences(doc => { doc.RunDirection(PdfRunDirection.RightToLeft); doc.Orientation(PageOrientation.Portrait); doc.PageSize(PdfPageSize.A4); doc.DocumentMetadata(new DocumentMetadata { Author = "Vahid", Application = "PdfRpt", Keywords = "Test", Subject = "Test Rpt", Title = "Test" }); }) .DefaultFonts(fonts => { fonts.Path(AppPath.ApplicationPath + "\\fonts\\irsans.ttf", Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\verdana.ttf"); }) .PagesFooter(footer => { footer.DefaultFooter(DateTime.Now.ToString("MM/dd/yyyy")); }) .PagesHeader(header => { header.DefaultHeader(defaultHeader => { defaultHeader.RunDirection(PdfRunDirection.RightToLeft); defaultHeader.ImagePath(AppPath.ApplicationPath + "\\Images\\01.png"); defaultHeader.Message("گزارش جدید ما"); }); }) .MainTableTemplate(template => { template.BasicTemplate(BasicTemplate.SilverTemplate); }) .MainTablePreferences(table => { table.ColumnsWidthsType(TableColumnWidthType.Relative); table.NumberOfDataRowsPerPage(5); }) .MainTableDataSource(dataSource => { dataSource.GenericDataReader( providerName: "System.Data.SQLite", connectionString: "Data Source=" + AppPath.ApplicationPath + "\\data\\blogs.sqlite", sql: @"SELECT [url], [name], [NumberOfPosts], [AddDate] FROM [tblBlogs] WHERE [NumberOfPosts]>=@p1", parametersValues: new object[] { 10 } ); }) .MainTableSummarySettings(summarySettings => { summarySettings.OverallSummarySettings("جمع کل"); summarySettings.PreviousPageSummarySettings("نقل از صفحه قبل"); summarySettings.PageSummarySettings("جمع صفحه"); }) .MainTableColumns(columns => { columns.AddColumn(column => { column.PropertyName("rowNo"); column.IsRowNumber(true); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(0); column.Width(1); column.HeaderCell("ردیف"); }); columns.AddColumn(column => { column.PropertyName("url"); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(1); column.Width(2); column.HeaderCell("آدرس"); column.ColumnItemsTemplate(template => { template.Hyperlink(foreColor: System.Drawing.Color.Blue, fontUnderline: true); }); }); columns.AddColumn(column => { column.PropertyName("name"); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(2); column.Width(2); column.HeaderCell("نام"); }); columns.AddColumn(column => { column.PropertyName("NumberOfPosts"); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(3); column.Width(2); column.HeaderCell("تعداد مطلب"); column.ColumnItemsTemplate(template => { template.TextBlock(); template.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)); }); column.AggregateFunction(aggregateFunction => { aggregateFunction.NumericAggregateFunction(AggregateFunction.Sum); aggregateFunction.DisplayFormatFormula(obj => obj == null ? string.Empty : string.Format("{0:n0}", obj)); }); }); columns.AddColumn(column => { column.PropertyName("AddDate"); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(4); column.Width(2); column.HeaderCell("تاریخ ثبت"); column.ColumnItemsTemplate(template => { template.TextBlock(); template.DisplayFormatFormula(obj => obj == null ? string.Empty : PersianDate.ToPersianDateTime((DateTime)obj) /*((DateTime)obj).ToString("dd/MM/yyyy HH:mm")*/); }); }); }) .MainTableEvents(events => { events.DataSourceIsEmpty(message: "There is no data available to display."); }) .Export(export => { export.ToExcel(); }) .Generate(data => data.AsPdfFile(AppPath.ApplicationPath + "\\Pdf\\RptSqlDataReaderSample.pdf")); } } }
توضیحات:
- در مثال فوق نحوه استفاده از یک بانک اطلاعاتی SQLite را ملاحظه میکنید. این بانک اطلاعاتی نمونه در پوشه bin\data سورس به روز شده پروژه موجود است.
dataSource.GenericDataReader( providerName: "System.Data.SQLite", connectionString: "Data Source=" + AppPath.ApplicationPath + "\\data\\blogs.sqlite", sql: @"SELECT [url], [name], [NumberOfPosts], [AddDate] FROM [tblBlogs] WHERE [NumberOfPosts]>=@p1", parametersValues: new object[] { 10 } );
در مرحله بعد به کمک GenericDataReader میتوان به این پروایدر دسترسی یافت. همانطور که ملاحظه میکنید یک کوئری پارامتری با مقدار پارامتر مساوی 10 جهت تهیه گزارش، تعریف شده است.
همچنین باید دقت داشت که اگر پروژه جاری شما مبتنی بر دات نت 4 است، نیاز خواهید داشت چند سطر زیر را به فایل config برنامه اضافه نمائید تا با SQLite مشکلی نداشته باشد:
<?xml version="1.0"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration>
- در حین معرفی ستون AddDate، نحوه نمایش و تبدیل تاریخ دریافتی که با فرمت DateTime است را به تاریخ شمسی ملاحظه میکنید. متد PersianDate.ToPersianDateTime در فضای نام PdfRpt.Core.Helper قرار دارد. توسط DisplayFormatFormula، فرصت خواهید داشت مقدار متناظر با سلول در حال رندر را پیش از نمایش، به هر نحو دلخواهی فرمت کنید.
- در ستون url از قالب نمایشی پیش فرض Hyperlink، برای نمایش اطلاعات فیلد جاری به صورت یک لینک قابل کلیک استفاده شده است.
یک نکته:
ذکر قسمت MainTableColumns و تمام تعاریف مرتبط با آن در PdfReports اختیاری است. به این معنا که میتوانید قسمت گزارش سازی و تعاریف گزارشات برنامه خود را پویا کنید (شبیه به حالت auto generate columns در گریدهای معروف). کوئریهای SQL متناظر با گزارشات را در بانک اطلاعاتی ذخیره کنید و به گزارش ساز فوق ارسال نمائید. حاصل یک گزارش جدید است.
- ExtJs چیست؟
- چه زمانی کاربرد دارد؟
- تفاوت آن با سایر فریم ورکهای جاوااسکریپ در چیست؟
پاسخ یک کلمه است: ExtJs. بله درست است در طراحی این CMS تنها از یک فریم ورک جاوااسکریپتی به نام ExtJs استفاده شده است. فریم ورکی که به عقیده بعضیها یک رویا برای توسعه دهندگان وب است و به عقیده سایرین شاید یک کابوس. در این پست قصد دارم به عنوان کسی که با این فریم ورک آشنایی دارم این موضوع را بررسی و مزایا و معایب این فریم ورک را عنوان کنم.
ExtJs یک فریم ورک جاوااسکریپ است بر مبنای Sencha و طراحی شده برای توسعه پروژههای وب در مقیاس بزرگ و به صورت cross-platform . مجوز استفاده از این فریم ورک به صورت GPLv3 است.(یعنی مجاز به استفاده رایگان از فایلهای این فریم ورک هستید به شرطی که قصد استفاده تجاری از پروژه تهیه شده را نداشته باشید! در غیر این صورت باید زحمت خرید نسخه تجاری این فریم ورک را متحمل شوید).
نسخه ای که درباره آن بحث میکنیم نسخه چهار این فریم ورک (ExtJs 4) که بر مبنای ExtJs 3 تولید شده است. تفاوت عمده آن با نسخه قبلی در تکمیل ابزار و کامپوننت هاست و از طرفی نسخه چهار این فریم ورک بر مبنای مدل MVC توسعه داده شده است. یعنی همانند Angular و BackBoneJs میتوانید مفاهیم کنترلر و مدل را به راحتی پیاده سازی کنید.
رویایی به نام ExtJs
اگر بخواهیم این فریم ورک را یک رویا برای توسعه دهندگان وب بنامیم میتوان عناوین زیر را به عنوان مزایا برشمرد:
- در درجه اول قابلیتی که این فریم ورک را متفاوت از سایر فریم ورکهای جاوااسکریپتی میکند
این است که این فریم ورک انبوهی از کامپوننتها و ویجیتهای آماده را به
همراه خود دارد (با کارایی و انعطاف پذیری قابل قبول) و به نوعی شما را بی نیاز از هرگونه مجموعه کامپوننتهای دیگر خواهد
کرد.
- این فریم ورک به خوبی از مباحت OOP پشتیبانی میکند و به این صورت است که یک
سری مفاهیم و مدلهای پایه در این فریم ورک تعبیه شده و به راحتی شما میتوانید مدلهای مورد نظر خود را بر اساس این مفاهیم و مدلهای پایه توسعه
دهید.
- تمام مفاهیم و ابزار لازم جهت درخواستهای Ajax ای و اعتبار سنجی سفارشی و
دستکاری عناصر DOM و... به خوبی در این فریم ورک وجود دارد.
- به دلیل وجود کامپوننتهای یک دست و آماده به راحتی میتوانید امکان تغییر theme را در پروزههای خود بدون کوچکترین زحمت قرار دهید.
- کنترل GridPanel،TreeView ، کنترلهای ورود اطلاعات، کنترل Tab با قابلیت درخواستهای لود صفحات به صورت Ajax و Async با کمترین زحمت در کد نویسی و هم چنین چارتهای بسیار گسترده و متنوع از دیگر مزایای این فریم ورک میتواند باشد.
- ارائه مکانیزمی مناسب برای کار با عملیات داده ای Json. به عنوان نمونه:
Ext.data.JsonP.request({ url: '@url', params: { apiKey: '1234' }, callbackKey: 'myCallbackFn', success: function(){ }, failure: function(){ }, scope: this });
- این فریم ورک ابزارهای جالب و کارآمدی برای توسعه به صورت SPA را داراست.
- کنترلهای داده ای این فریم ورک در هنگام کار با حجم داده بسیار زیاد، فراتر از انتظار عمل میکنند(برای مثال کنترل GridPanel و DataView)
- اگر قصد تولید و توسعه بک پروژه بزرگ درون سازمانی را دارید و سرعت تولید نیز برای شما مهم است ExtJs در این زمینه کمک شایانی به شما خواهد کرد.
- و...
حال با همه این تفاسیر آیا این فریم ورک یک رویا برای هر توسعه دهنده وب خواهد بود؟
به طور قطع نه. با توجه به اصل واقع بینی! همواره به خاطر داشته باشید که
اگر این فریم ورک یک ابزار بی نقص و همه منظوره بود الآن مطمئنا صدها کتاب و
مستندات درباره آن نوشته شده بود و شاید شهرتی بس فراتر از این داشت.
کابوسی به نام ExtJs
- اگر قصد ایجاد یک وب سایت کوچک و جمع و جور را دارید به طوری که مباحث مربوط به SEO نیز برای شما اهمیت دارد تجربه نشان داده است که انتخاب ExtJs میتواند یکی از بزرگترین اشتباهات در طول عمر کاری شما شود.
- ExtJs هیچ گونه کمکی برای تولید و توسعه اپلیکیشنهای موبایل یا پروژههای وب گرافیکی نمیتواند به شما کند.
- اگر سرعت یکی از فاکتور خیلی مهم برای شماست بهتر است به این فریم ورک علاقه نشان ندهید.(کتابخانه آن چیزی در حدود 500KB است! البته با فشرده سازی به 150KB خواهد رسید که باز هم قابل قبول نیست)
- مجوز استفاده برای پروژههای تجاری به صورت رایگان نیست.(^)
- به دلیل وجود ابزارهای متنوع و زیاد؛ زمان یادگیری برای آشنایی و کار کردن با ابزارها، نسبتا طولانی خواهد شد.
- کد نویسی برای استفاده از ابزارهای آن در مقایسه با Jquery و Angular بیشتر خواهد بود(البته این به نوعی مزیت هم است، به دلیل اینکه خوانایی کدها بسیار بالا میرود)
- در طراحی کامپوننتها آن از تگ div در حد غیر قابل قبول استفاده شده است به طوری که Debug صفحات حتی با Firebug هم در بعضی مواقع سخت میشود.
- و...
Ext.Net چیست؟
Ext.Net یک پیاده سازی خاص از فریم ورک ExtJs است که برای توسعه پروژههای Asp.Net Web Forms و Asp.Net MVC طراحی شده است. تفاوت اصلی بین این دو محصول در نوع کدنویسی برای استفاده در پروژههای Asp.Net است. برای مثال در هنگام کار با Ext.Net و پروژههای MVC از آنجا که این محصول سازگاری کامل با موتور Razor دارد به راحتی میتوانید به صورت سینتکس Razor صفحات خود را طراحی کنید.
مثال:
ExtJs
Ext.create('Ext.panel.Panel', { title: 'Fit Layout', width: 500, height: 200, items: { title: 'Inner Panel', html: 'Panel content', bodyPadding: 10, border: true }, renderTo: Ext.getBody() });
Ext.Net
@(X.Panel() .ID("ExpandablePanel") .Title("Panel") .Width(500) .Height(300) .Collapsible(true) .Loader(X.ComponentLoader() .Url(Url.Action("RenderChild")) .Mode(LoadMode.Frame) .DisableCaching(true) .Params(new { containerId = "ExpandablePanel" }) .LoadMask(lm => lm.ShowMask = true) ) .Listeners(l => { l.Expand.Handler = "this.reload();"; l.Collapse.Handler = "this.clearContent();"; }) )
جمع بندی:
با توجه مواردی که ذکر شد میتوان به یک نکته مهم رسید و آن هم این است که هنگام انتخاب ExtJs یا Ext.Net (البته این شامل اکثر ابزارهای توسعه دیگر نیز خواهد شد) حتما شرایط موجود و حاکم برای توسعه محصول را مد نظر داشته باشید که این شرایط شامل محیط اجرای محصول، مدت زمان لازم برای توسعه، سطح دانش نیرویهای توسعه دهنده و ... نیز میباشد.
زبان برنامه نویسی Ecstasy که اخیرا در کنفرانس Cloud Native 2019 معرفی شده است، در تلاش است تا توسعه، نگهداری و بروزرسانی راهکارهای نرم افزاری مدرن که احتمالا در Cloud Providerهای مختلف اجرا میشوند، را تسهیل بخشد.
در این زبان سعی شده تا تمام وابستگیهای برنامه ها، از طریق تزریق وابستگی و توسط Runtime مدیریت شود و پشتیبانی از AOT و WASM ازجمله ویژگیهای آن است. پشتیبانی از نسخههای مختلف یک ماژول در ماژول دیگر از ویژگیهای جذاب آن است که میتواند نحوه انتشار و پشتیبانی نرم افزاری را در سازمانها متحول کند. البته این زبان همچنان در حال توسعه است و برای استفاده در محیطهای عملیاتی آماده نیست و بخشی از ابزارهای آن هنوز در حال تکمیل است.
مخزن پروژه: https://github.com/xtclang/
وب سایت پروژه: https://xtclang.org/