ASP.NET Web API - قسمت چهارم
سلام آقای راد
با تشکر از زحمتی که میکشید. فرمودید که :
"بنابراین web api به دنبال متدی در controller میگردد که نام آن با عبارت get "آغاز" شده باشد. "
آیا این کار باعث عدم دقت و ایجاد خطاهای ناخواسته نمیشه؟ این فقط متدی با get شروع بشه شاید برای من که خیلی کم mvc کار کردم یکم مشکل دار به نظر برسه.اگر ما دو متد داشته باشیم که در ابتدای آنها get باشد آیا برنامه خطا میگیرد؟ ممنون میشم یکم در این باره توضیح بدین
لیست مثالهای همراه با سورس کد PdfReport
• AccountingBalanceColumn/
چگونه باید از مقدار مانده ردیف قبلی در محاسبات ردیف جاری استفاده کرد (چیزی شبیه به گزارشات دفتر کل حسابداری).
• AcroFormTemplate/
چگونه میتوان از قالبهای سفارشی تهیه شده توسط Open office در PdfReport استفاده کرد. اگر در یک سلول قرار است قالب پیچیدهای را نمایش دهید، یکی از روشهای انجام کار استفاده از قالبهای AcroForm است.
• AdHocColumns/
چگونه تولید ستونهای گزارشات را پویا کنیم (بدون نیاز به تعریف جزئیات آنها). برای مثال اگر هربار کوئری متفاوتی را ارسال میکنید یا از منابع داده مختلفی با تعداد ستونهای متغیر در گزارش نهایی استفاده میشود، میتوانید با حذف قسمت تعاریف ستونها، این نوع گزارشات پویا را تهیه نمائید.
• AnnotationField/
نمایشی از قالب سلول سفارشی AnnotationField. Annotationها اشیایی خاص در فایلهای PDF هستند که امکان نوشتن توضیحات طولانی را فراهم میکنند و نهایتا به شکل یک آیکون در گزارش ظاهر خواهند شد.
• Barcodes/
مثالی در مورد نحوه تولید انواع بارکدهای مختلف مانند barcode 128 و barcode 39
• CalculatedFields/
چگونه بر اساس فیلدهای موجود یک گزارش، ستون محاسبه شده جدیدی را تولید کنیم. همچنین مواردی مانند فرمت کردن عدد نمایش داده شده و اضافه کردن جمع به یک ستون نیز در این گزارش لحاظ شده است.
• CharacterMap/
گزارشی شبیه به برنامه معروف character map ویندوز. در این گزارش نوع جدول به TableType.HorizontalStackPanel تنظیم شده است. به این ترتیب رکوردهای تولید شده به صورت افقی و پی در پی نمایش داده خواهند شد.
• ChartImage/
نحوه قرار دادن نمودارهای MS Chart را در گزارشات، در این مثال مشاهده خواهید کرد.
• CsvToPdf/
چگونه رکوردهای یک فایل CSV را تبدیل به فایل PDF کنیم؟ این مثال در حقیقت نحوه استفاده مستقیم از نتایج کوئریهای LINQ را بیان میکند.
• CustomCellTemplate/
چگونه یک قالب سلول سفارشی را تعریف کنیم. یک سری قالب پیش فرض مانند تصویر، متن و غیره در PdfReport به ازای هر سلول قابل تعریف است. اگر این موارد نیاز کاری شما را برآورده نمیکنند، میتوانید آنها را سفارشی سازی کنید.
• CustomHeaderFooter/
چگونه هدر و فوتر گزارشات را سفارشی سازی کنیم؟
• CustomPriceNumber/
چگونه یک قالب سلول سفارشی را جهت نمایش ویژه عدد مبلغ هر ردیف به شکل یک جدول پر شده از اعداد ایجاد کنیم.
• DataAnnotations/
چگونه تعاریف خواص ستونها را به کمک data annotations انجام داده و اینکار را سادهتر نمائیم. با استفاده از data annotations نیز میتوان قسمت تعاریف ستونها را کاملا حذف کرد.
• DbImage/
چگونه تصاویر ذخیره شده در بانک اطلاعاتی را در گزارشات نمایش دهیم.
• DigitalSignature/
چگونه امضای دیجیتال را به گزارشات PDF خود اضافه نمائیم.
• DuplicateColumns/
چگونه از ستونهایی هم نام، استفاده کنیم. برای مثال اگر از دو جدول کوئری میگیرید و دو فیلد به نامهای name اما با معانی و مقادیری متفاوت تعریف شدهاند، چگونه باید ایندکس آنها را جهت تمایز بهتر معرفی کرد.
• DynamicCompile/
چگونه سورس یک گزارش PdfReport را به صورت پویا از یک فایل متنی ساده خوانده و کامپایل کنیم.
• DynamicCrosstab/
چگونه یک گزارش Crosstab پویا را تعریف کنیم. برای مثال گزارشی که تعداد ستونهای آن نامشخص است و هر بار بر اساس بازه روزهای گزارشگیری تعیین میشود.
• EmailInMemoryPdf/
چگونه یک فایل Pdf تولید شده را به صورت خودکار به مقصدی خاص ایمیل کنیم.
• Events/
چگونه میتوان دقیقا پیش و پس از یک گزارش، تعاریف و عناصر دلخواه خود را اضافه کنیم؟
• ExcelToPdf/
چگونه یک فایل اکسل را تبدیل به گزارش PdfReport کنیم؟
• ExpensesCrosstab/
مثالی دیگر از نحوه تولید گزارشات Crosstab.
• ExtraHeadingCells/
چگونه گزارشاتی را تولید کنیم که هدر آنها بیش از یک ردیف است.
• Grouping/
نحوه گروه بندی اطلاعات را در این گزارش بررسی خواهیم کرد.
• HexDump/
یک گزارش ویژه از منبع دادهای anonymously typed.
• HtmlCellTemplate/
چگونه میتوان از Html جهت ساده سازی تعریف سلولهای پیچیده که بیش از یک مقدار را نمایش میدهند استفاده کرد.
• HtmlHeader/
چگونه میتوان از Html برای ساده سازی هدر گزارش استفاده کرد.
• HtmlHeaderRtl/
نسخه راست به چپ و فارسی مثال قبل.
• IList/
چگونه میتوان از لیستهای جنریک گزارش تهیه کرد.
• ImageFilePath/
چگونه میتوان از تصاویر ذخیره شده در فایل سیستم، گزارش گرفت.
• InjectCustomRows/
چگونه میتوان ردیفی سفارشی را در بین ردیفهای دریافت شده از بانک اطلاعاتی قرار داد.
• InlineProviders/
چگونه میتوان تعاریف سفارشی سلولها را در همان محل تعریف گزارش به نحوی سادهتر تعریف کرد.
• InMemory/
نحوه تولید فایلهای PDF درون حافظهای، مناسب جهت برنامههای وب ASP.NET (بدون نیاز به ذخیره فایل بر روی سرور)
• MailingLabel/
چگونه گزارشهای معروف برچسبهای چاپی را توسط PdfReport تولید کنیم.
• MasterDetails/
چگونه از روابط one-to-many بین دو جدول گزارش گیری کنیم؟
• MergePdfFiles/
چگونه از چند منبع داده مختلف استفاده کرده و نهایتا گزارشات حاصل را یکی و تبدیل به یک فایل PDF کنیم. برای نمونه استفاده از سه جدول مختلف با هدرها و سرستونهای متفاوت و سپس تولید یک گزارش یکپارچه از این سه، در قالب یک فایل نهایی. به علاوه در این مثال نحوه بازنویسی فوتر موجود نیز نمایش داده شده است (توسط WriterCustomizer آن).
• MonthCalendar/
چگونه در گزارشات، تقویم میلادی را نمایش دهیم.
• PdfA/
چگونه خروجی PDF حاصل را بر اساس استاندارد PdfA که مخصوص آرشیو و نگهداری است، تولید کنیم.
• PersianFontsListToPdf/
چگونه از لیست قلمهای نصب شده در سیستم گزارش Pdf تهیه کنیم.
• PersianMonthCalendar/
بررسی نحوه نمایش تقویم شمسی، در گزارشات.
• PersianRtl/
بررسی امکانات فارسی توکار کتابخانه PdfReport؛ مانند تهیه گزارشات راست به چپ، تاریخ شمسی، عدد به حروف و غیره.
• ProgressReport/
چگونه درصد پیشرفت یک عملیات را در سلولها نمایش دهیم. همچنین نحوه ایجاد گزارشات چند ستونی، برای صرفه جویی در میزان کاغذ مصرفی چاپ گزارشات را نیز در این گزارش مشاهده خواهید نمود.
• QuestionsAcroForm/
مثالی در مورد نحوه استفاده از قالبهای PDF تولید شده توسط Open office برای تولید برگه سؤالات امتحانی
• QuestionsForm/
مثالی در مورد نحوه طراحی برگه سؤالات امتحانی توسط سفارشی سازی سلولها در PdfReport
• SQLiteDataReader/
چگونه از یک بانک اطلاعاتی SQLite گزارش تهیه کنیم.
• StackedProperties/
چگونه در یک گزارش، در یک سلول بیش از یک فیلد را نمایش دهیم.
• Tax/
چگونه یک گزارش فاکتور فروش طراحی کنیم.
• WorkedHours/
چگونه گزارش حضور و غیاب پرسنل را تهیه کنیم.
• WrapGroupsInColumns/
چگونه گزارشات چندستونی را تولید کنیم.
• XmlToPdf/
چگونه دادههای یک فایل XML را تبدیل به گزارش کنیم.
• ZapfDingbatsSymbols/
چگونه از قلم مخصوص Symbols شرکت Adobe برای نمایش اشکال مختلف میتوان استفاده کرد.
هر بیزینس آبجکت داخلی رو بین یک GroupHeader و GroupFooter قرار دادم. من این بیزینس آبجکتهای داخلی رو با درگ کردن درون محیط دیزاین قرار دادم. مشکلی که وجود داره اینه که وقتی خروجی گزارش توی برنامه تکراری هست. یعنی اینکه اطلاعات بیزینس آبجکتهای LanguageCourses و... چند بار توی خروجی تکرار میشه. مشکل هم از پاس دادن اطلاعات توی اکشن نیست. اونجا اطلاعات درست پاس داده میشه. و جالب اینجاست که مثلا اگر من فقط دوتا بیزینس آبجکت LanguageCourses و Education رو توی گزارش بذارم اطلاعات این دوتا، دوبار تکرار میشه. اگه یه بیزینس آبجکت دیگه (مثلا TrainingCourses) رو هم بیارم تو گزارش، اطلاعات هر کدوم از این سه تا، سه بار تکرار میشه!
چند روز همین مشکل منو درگیر کرده و هنوز هم به نتیجه ای نرسیدم.
ممنون میشم دوستان راهنمایی کنند.
فایل گزارش: Report-9b7bd75b5286457a96f25f7ed37e45b6.mrt
نشان دادن گزارش قبل از ذخیره یا چاپ
ساختار گزارش خاص
ASP.NET MVC #17
سلام
من مرتبا با خطای AntiForgeryToken مواجه میشم.
یکبار این پیغام صرفا بر روی host ایجاد میشه وگاهی وقتها هم بر روی لوکال. کلیه ورود اطلاعات را با این فیلتر امنیتی مشخص کردم . در اینترنت جستجو کردم و خیلیها این مشکل داشتند و پیشنهاد کردن که در WebConfig نوع الگوریتم و کلید کد و دیکد را مشخص کنم، اما میخواستم بدونم اصلا علت بروز گه گاه این خطا چیست و چرا همیشگی نیست و مشخص کردن کد و الگوریتم کار صحیحی هست یا خیر؟
دارا بودن امکانات بسیار قدرتمند و پشتیبانی از محیط فارسی و همچنین پشتیبانی آنها جهت پاسخگویی به سوالات، چه از طریق ایمیل یا چت، از نقاط قوت این ابزار به شمار میروند. در جدول مقایسات میتوانید تفاوت نسخههای موجود این گزارش ساز را مشاهده کنید. برای استفاده در MVC از نسخه وب آن استفاده میکنیم.
در این مقاله قصد داریم با نحوه راه ندازی این ابزار در وب (MVC) آشنا شویم که شامل مباحث زیر میشود:
- استفاده از EF به عنوان منبع داده و ارسال آنها به سمت گزارش ساز
- نحوه طراحی فایل MRT و بایند کردن دادههای اطلاعاتی و ایجاد جدول
- استفاده از امکانات فایل خروجی ، چاپ و پیش نمایش و...
- بررسی Direction جهت استفاده در محیطهای فارسی زبان
- نحوه ارسال اطلاعات بین دو اکشن متفاوت
طراحی فایل MRT
فایل MRT در واقع یک قالب (Template) خالی از مقادیر متغیر است که در StimulSoft Studio به طراحی آن میپردازیم و در برنامه خود، این مقادیر متغیر را با اطلاعات دلخواه خود جایگزین میکنیم. تصویر زیر یک نمونه از یک گزارش خالی است که ابتدا آن را طراحی کرده و سپس در برنامه آن را مورد استفاده قرار میدهیم:
برای اینکه فایل MRT بتواند دیتاهای لازمی را که به آن پاس میدهیم، بخواند و در جای مشخص شده قرار بدهد، باید یک BussinessObject برای آن ایجاد کنیم. بعد از اینکه یک گزارش جدید ایجاد کردید، در سمت راست به قسمت Dictionary بروید و در قسمت BussinessObject گزینه NewBussinessObject را انتخاب کنید. یک نام و نام مستعار که عموما هم یکی است، برای آن انتخاب کنید. در زیر همان پنجره شما میتوانید ستونهای اطلاعاتی خود را تعریف کنید. در اینجا من میخواهم اطلاعات یک راننده را به همراه خودروی وی، نشان دهم. برای همین، من دو موجودیت راننده و خودروی راننده را دارم. پس اسم Business Object را DriverReport میگذارم و ستونهای اطلاعاتی فقط راننده (بدون در نظر گرفتن خودروی وی) را وارد میکنم.
در همین کادر بالا شما میتوانید تصیم بگیرید که آیا میخواهید اطلاعات خودرو را به همراه دیگرستونهای اطلاعاتی راننده، ایجاد کنید یا اینکه برای خودرو یک نوع مجزا انتخاب کنید. اگر تنها یک خودرو برای راننده باشد، شاید راحتتر باشید همانند اطلاعات راننده با آن رفتار کنید. ولی اگر مثلا بخواهید خودرویهای گذشته راننده را هم جز لیست داشته باشید، بهتر است یک Business Object جدید متعلق و زیر مجموعه Business Object راننده ایجاد کنید. در اینجا چون تنها یک خودرو است، من آن اطلاعات آن را به همراه راننده، ارسال میکنم. شکل زیر ساختار درختی از گزارش بالاست:
شکل زیر هم یک ساختار دیگر از یک گزارش است که شامل Business objectهای مختلف میشود:
سپس همین فیلدها را به سمت صفحه خالی بکشانید. با دو بار کلیک روی فیلدهای قرار گرفته در صفحه، با نحوه بایند کردن مقادیر آشنا میشوید؛ هر فیلدی که قرار است دیتای آن بایند شود، باید به شکل زیر در بخش Expression پنجره باز شده، نوشته شود:
{driverReport.LastName}
در دیکشنری همچنین انواع دیگری از فیلدها نیز به چشم میخورد:
متغیرها: این نوع فیلد یک متغیر است که به طور جداگانه میتواند مقداردهی شود و از آن بیشتر برای ارسال دادههای تکی چون تصاویر، تاریخ شمسی و ... میتوان استفاده کرد.
متغیرهای سیستمی: این نوع متغیرها توسط خود گزارش ساز به طور مستقیم پر میشوند که شامل شماره صفحه، تاریخ و زمان، تعداد صفحات، مقادیر دو ارزشی (آیا صفحه آخر گزارش است؟) و ... میشود.
توابع: گزارش ساز شامل یک سری توابع آماده برای اعمال تغییرات بر روی دادهها میباشد که در دستههای مختلفی چون کار با رشتهها، زمان، ریاضیات و... قرار گرفتهاند.
بعد از تکمیل آن، فایل MRT را ذخیره و در یک دایرکتوری در ساختار پروژه قرار دهید.
راه اندازی گزارش ساز در ASP.Net MVC
اولین کاری که میکنیم، ورود سه dll اصلی به پروژه است:
Stimulate.Base
Stimulate.Report
Stimulate.Report.MVC
در مرحله بعد یک متد ساخته و یک ویوو را برای صفحه گزارش گیری ایجاد میکنیم:
public ActionResult Report(int id) { return View(); }
@Html.Stimulsoft().StiMvcViewer(new StiMvcViewerOptions() { Localization = "~/content/reports/fa.xml", Actions = { GetReportSnapshot = "LoadReportSnapshot", ViewerEvent = "ViewerEvent", ExportReport = "ExportReport", PrintReport = "PrintReport", } }
در نسخههای دو سال اخیر، استفاده از این Helper تفاوتهایی در نحوه استفاده از خصوصیتهای آن کرده است. در این روش جدید، پراپرتیها دسته بندی شده و برای دسترسی به هر کدام باید به بخش آن مراجعه کنید؛ مثلا پراپرتیهای Action، در دسته Actions قرار گرفتهاند یا خصوصیتهای ظاهری در دسته Appearance، یا گزینههای مرتبط با خروجی گرفتنها، در دسته Export قرار گرفتهاند و الی آخر که در نسخههای پیشین، کد بالا را به شکل زیر، با پیشوند نام دسته مینوشتیم:
@Html.Stimulsoft().StiMvcViewer(new StiMvcViewerOptions() { Localization = "~/content/reports/fa.xml", ActionGetReportSnapshot = "LoadReportSnapshot", ActionViewerEvent = "ViewerEvent", ActionExportReport = "ExportReport", ActionPrintReport = "PrintReport", }
بعد از آن لازم است دیتاها را از طریق EF خوانده و به یک مدل جدید که بر اساس اطلاعات گزارش شماست و قرار است گزارش شما این پراپرتیها را بشناسد، به طور دستی یا با استفاده یک کتابخانه mapping مثل automapper انتقال دهید. یا حتی میتوانید مانند کد زیر از ساختاری ناشناس استفاده کنید. در کد زیر، من به صورت تمرینی اطلاعات یک راننده و خودروی او را انتقال میدهم:
var driver = new { FirstName = "علی", LastName = "یگانه مقدم", NationalCode = "12500000000", FatherName = "حسین", Model = "نام خودرو", MotorNumber = 415244, ProductionYear = 1394, Capacity = 4 };
var driver = new { FirstName = "علی", LastName = "یگانه مقدم", NationalCode = "12500000000", FatherName = "حسین", car = new { Model = "نام خودرو", MotorNumber = 415244, ProductionYear = 1394, Capacity = 4 } };
var report = new StiReport(); report.Load(Server.MapPath("~/Content/Reports/driver.mrt")); report.RegBusinessObject("driverReport", driver); report.Dictionary.Variables.Add("today", DateTime.Today.ToPersianString(PersianDateTimeFormat.Date));
var report = new StiReport(); report.RegBusinessObject("driverReport", driver); report.Dictionary.Variables.Add("today", DateTime.Today.ToPersianString(PersianDateTimeFormat.Date)); report.Load(Server.MapPath("~/Content/Reports/driver.mrt"));
پس کد کامل ما برای ایجاد یک گزارش به شکل زیر میشود:
public ActionResult LoadReportSnapshot() { var driver = new { FirstName = "علی", LastName = "یگانه مقدم", NationalCode = "12500000000", FatherName = "حسین", Model = "نام خودرو", MotorNumber = 415244, ProductionYear = 1394, Capacity = 4 }; var report = new StiReport(); report.Load(Server.MapPath("~/Content/Reports/driver.mrt")); report.RegBusinessObject("driverReport", driver); report.Dictionary.Variables.Add("today", DateTime.Today.ToPersianString(PersianDateTimeFormat.Date)); return StiMvcViewer.GetReportSnapshotResult(HttpContext, report); }
اگر دوباره در ویو مربوطه، به سراغ helper برویم میبینیم که سه اکشن متد دیگر وجود دارند که در زیر، به ترتیب با نحوه کار آنها و کد اکشن متد آنها اشاره میکنیم:
Viewer Events : این اکشن متد که تنها یک خط ActionResult استاتیک را فراخوانی میکند، جهت مدیریت رویدادهای گزارش چون: زوم، صفحه بندی گزارش، خروجیها و چاپ میباشد و وجود آن در گزارش از الزامات است.
public virtual ActionResult ViewerEvent() { return StiMvcViewer.ViewerEventResult(); }
PrintReport: برای مدیریت و ارسال گزارشات به دستگاه چاپ میباشد. این اطلاعات از طریق شی HttpContext به سمت اکشن متد ارسال شده و توسط PrintReportResult آن را دریافت میکند.
public virtual ActionResult PrintReport() { return StiMvcViewer.PrintReportResult(this.HttpContext); }
ExportReport: گزارش ساز استیمول به شما اجاز میدهد در فرمتهای گوناگونی چون xlsx,docx,pptx,pdf,rtf و ... از گزارش خود خروجی بگیرید. اطلاعات گزارش از طریق شی HttpContext به سمت اکشن متد ارسال شده و توسط ExportReportResult دریافت میشود.
public virtual ActionResult ExportReport() { return StiMvcViewer.ExportReportResult(this.HttpContext); }
البته خوشبختانه این مشکل در حالت پیش نمایش و چاپ و خروجیها دیده نمیشود و فقط مختص نمایش روی فرم Html است. برای حل این مشکل ممکن است از گزینه یا پراپرتی RightToLeft، در بخش Appearance موجود در helper استفاده کنید که البته استفاده از آن مانند تصویر بالا، فقط محدود به container گزارش و نوار ابزار آن میشود. برای حل این مشکل کافی است کد css زیر را به صفحه گزارش اضافه کنید تا مشکل حل شود:
.stiMvcViewerReportPanel table{ direction:ltr !important; }
حال حتما پیش خود میگویید که این روش برای اطلاعات ایستا و تمرینی مناسب است و من چگونه باید پارامترهای ارسالی به اکشن متد Report را به اکشن متد LoadReportSnapshot ارسال کنم. برای این منظور استفاده از SessionStateها زیاد توصیه شدهاست:
public virtual ActionResult Report(int id) { TempData["id"]=id; return View(); } public virtual ActionResult LoadReportSnapshot() { var driverId = (int)TempData ["id"]; //..... }
public virtual ActionResult Report(int id) { return View(); } public virtual ActionResult LoadReportSnapshot(int id) { //..... }
نکته بسیار مهم: گزارش ساز استیمول متاسفانه شامل تنظیم پیش فرض نامناسبی است که عملیات کش را بر روی گزارشها اعمال میکند. به عنوان مثال تصور کنید من صفحه گزارش شخصی به نام «وحید نصیری» را باز میکنم و در تب دیگر گزارش شخص دیگری با نام «علی یگانه مقدم» را باز میکنم. حال اگر کاربر به سراغ تب آقای نصیری برود و بخواهد چاپ یا خروجی درخواست کند، اشتباها با گزارش علی یگانه مقدم روبرو خواهد شد که این اتفاق به دلیل کش شدن رخ میدهد. برای غیر فعال کردن این قابلیت پیش فرض، کد زیر را در Helper اضافه کنید:
Server = { GlobalReportCache = false }
راهنمایی در مورد چیدن اجزای گزارش
events.MainTableAdded(args => { var infoTable = new PdfGrid(numColumns: 2) { WidthPercentage = 80 ,SpacingAfter = 50,SpacingBefore = 50}; infoTable.AddSimpleRow( (cellData, properties) => { cellData.Value = "پویا"; properties.ShowBorder = false; properties.BorderWidth = 0; properties.BorderWidth = 000; properties.PdfFont = events.PdfFont; properties.RunDirection = PdfRunDirection.RightToLeft; }, (cellData, properties) => { cellData.Value = "امینی"; properties.ShowBorder = false; properties.BorderWidth = 0; properties.BorderWidth = 000; properties.PdfFont = events.PdfFont; properties.RunDirection = PdfRunDirection.RightToLeft; } ); args.PdfDoc.Add(infoTable.AddBorderToTable()); });
که نتیجه نهایی آن به صورت زیر است
با اینکه من properties.ShowBorder = false; قرار دادم ولی باز هم یک حاشیه برای آن در نظر میگیرد.حال من میخواهم Border جدول حذف شود هر کاری میکنم Border حذف نمیشود ممنون میشم راهنمایی کنید.