نظرات مطالب
CAPTCHAfa
چه جالب!
امیدوارم استفاده از کپتچای فارسی در سایت‌های فارسی مرسوم بشه
مطالب
نمایش یک پیغام به کاربر در ASP.Net

عموما در برنامه‌های وب مرسوم است که پیغام به کاربر را در همان لابلای html صفحه نمایش می‌دهند. مثلا یک برچسب و سپس تنظیم متن آن در کد برنامه به صورت پویا.
با استفاده از پلاگین‌های jQuery این‌کار را به صورت شکیل‌تری می‌توان انجام داد. برای مثال:


پلاگین کم حجمی برای این منظور موجود است به نام jQuery Notice (یکی از چند ده نمونه موجود)
<script type="text/javascript">
$(document).ready(function()
{
jQuery.noticeAdd({
text: 'پیغامی به کاربر',
stay: false
});
});
</script>
کمی این پلاگین را اصلاح کردم تا مشکل عدم نمایش آن هنگام اسکرول طولانی صفحه در IE حل شود (به صورت پیش فرض با فایرفاکس مشکلی ندارد). برای مثال این div را در نظر بگیرید:
<div id="myElement" style="position: absolute">This stays at the top</div>
قصد داریم مکان آن‌را در بالای صفحه ثابت کنیم (حتی با یک اسکرول طولانی مانند تصویر فوق، باز هم همان بالا باقی بماند و قابل مشاهده باشد).
با استفاده از jQuery این‌کار به صورت زیر قابل انجام است:
<script type="text/javascript">
$(document).ready(function()
{
$(window).scroll(function() {
$('#myElement').css('top', $(this).scrollTop() + "px");
});
});
</script>
زمانیکه scroll ایی در window جاری صورت ‌گیرد، div ایی با id مساوی myElement یافت شده و سپس مقدار top آن تنظیم شده و در بالای صفحه نمایش داده می‌شود.

ولی این روش جهت نمایش پیغامی پویا به کاربر مشکل دارد.
نیاز است به ازای هر پیغام پویا یکبار به نحوی این اسکریپت به صفحه تزریق شود که روش انجام کار در ASP.Net به صورت زیر می‌تواند باشد:

using System;
using System.Web.UI;
using System.Web;

public class CAddJqueryNotice
{
/// <summary>
/// نمایش یک پیغام بر اساس پلاگین نوتیس
/// </summary>
/// <param name="title">عنوان</param>
/// <param name="msg">پیغام</param>
/// <param name="rtl">راست به چپ؟</param>
/// <param name="duration">مدت زمان نمایش</param>
/// <param name="autoHide">به صورت خودکار بسته شود؟</param>
public static void Show(string title, string msg, bool rtl, int duration, bool autoHide)
{
string scriptBlock
= string.Format(@"<script type=""text/javascript"">
$(document).ready(function() {{
jQuery.noticeAdd({{
text: '<b>{0}</b><br/><div align=left dir={1}>{2}</div>',
stay: {3},
stayTime: {4}
}});
}});
</script>",
title,
(rtl ? "rtl" : "ltr"),
msg,
(autoHide ? "false" : "true"),
duration);

if (HttpContext.Current == null || HttpContext.Current.Handler == null) return;
Page page = HttpContext.Current.Handler as Page;
if (page != null)
page.ClientScript.RegisterStartupScript(
page.GetType(),
"script" + new Guid().ToString("N"),
scriptBlock,
false);
}

}
از آنجائیکه در یک کلاس دیگر خارج از صفحه اصلی مشغول به کار هستیم، دسترسی مستقیم به شیء Page و سپس متد ClientScript.RegisterStartupScript آن جهت تزریق اسکریپت خود به صفحه نداریم. اما با استفاده از HttpContext.Current.Handler می‌توان به این مقصود رسید و مشکل حل می‌شود.

برای آزمایش آن یک دکمه را در صفحه قرار داده و در روال رخ‌داد گردان کلیک آن کد زیر را اضافه کنید:
CAddJqueryNotice.Show( "لطفا دوباره سعی کنید", "مشکلی رخ داده است", true, 2000, true);

بدیهی است قبل از استفاده از کد فوق، باید چند سطر زیر را به هدر master page سایت خود اضافه کنید:
<script src="jquery-1.3.2.js" type="text/javascript"></script>
<link href="jquery.notice.css" type="text/css" media="screen" rel="stylesheet" />
<script src="jquery.notice.js" type="text/javascript"></script>

نظرات مطالب
اعمال تزریق وابستگی‌ها به مثال رسمی ASP.NET Identity
با تشکر از توجه شما. 
در این پروژه نمونه و با همین تنظیمات، شرایط بدین گونه است: 
کاربر سایت را به صورت ناشناس مشاهده می‌کند. سپس با اطلاعات خود وارد سایت می‌شود. پس از تعییت هویت، مثلا به بخش Product هم دسترسی پیدا می‌کند. تا این مرحله همه چیز خوب است و خیر. سپس از حساب خود خارج می‌شود و دقایقی بعد، مجددا وارد حساب خود می‌شود. از این لحظه به بعد، رفتار برنامه متفاوت می‌شود. چرا که با وجود اینکه کاربر تایید هویت شده، اما اگر بخواهد مثلا دوباره به همان بخش Product مراجعه کند، سیستم ابتدا او را به صفحه‌ی ورود هدایت کرده و با کاربر، به عنوان یک کاربر ناشناخته برخورد می‌کند. همین گونه است برای سایر قسمتهایی که صفت Authorize  برای آنها لحاظ شده. پرسش من این است که آیا این رفتار طبیعی ست؟
قبلا گفتم که با تغییر مقدار validateInterval   ظاهرا این مشکل بر طرف می‌شود. لااقل این رفتار تغییر می‌کند. شما  فرمودید که در نظرگرفتن هر عددی جز صفر، موجب می‌شود تا کوکی بلافاصله به روز نشود. این صحبت شما کاملا صحیح و منطقی. اما آیا ورودهای مکرر به نظر شما منطقی ست؟
به کدهای این پروژه هم دقت کردم. مقدار validateInterval   برابر با 30 لحاظ شده که ظاهرا نباید اینگونه باشد. برای اینکه هم به رویکردی که شما به آن اشاره کردید برسیم و هم کاربر مجبور نباشد مدام Login کند، لطفا بفرمایید که چه تغییراتی لازم است؟ در صورتیکه من اشتباه کرده ام و یا چیزی را ندیده و یا از قلم انداخته ام، لطف می‌کنید اگر راهنمایی بفرمایید.
مطالب
تبدیل صفحات یک فایل PDF به تصویر، با استفاده از Acrobat SDK
با استفاده از اشیاء Com همراه با Acrobat SDK می‌توان تمام صفحات یک فایل PDF را تبدیل به تصویر کرد. این SDK به همراه نگارش کامل Adobe Acrobat نیز بر روی سیستم نصب می‌شود و یا می‌توان آن‌را به صورت جداگانه از سایت Adobe دریافت کرد.
پس از آن، برای تبدیل صفحات یک فایل PDF به تصویر، مراحل زیر باید طی شود:
الف) وهله سازی از شیء AcroExch.PDDoc
در صورتیکه SDK یاد شده بر روی سیستم نصب نباشد، این وهله سازی با شکست مواجه خواهد شد و همچنین باید دقت داشت که این SDK به همراه نگارش رایگان Adobe reader ارائه نمی‌شود.
ب) گشودن فایل PDF به کمک شیء Com وهله سازی شده (pdfDoc.Open)
ج) دریافت اطلاعات صفحه مورد نظر (pdfDoc.AcquirePage)
د) کپی این اطلاعات به درون clipboard ویندوز (pdfPage.CopyToClipboard)
به این ترتیب به یک تصویر Bmp قرار گرفته شده در clipboard ویندوز خواهیم رسید
ه) مرحله بعد تغییر ابعاد و ذخیره سازی این تصویر نهایی است.

کدهای زیر، روش انجام این مراحل را بیان می‌کنند:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using Acrobat; //Add a Com Object ref. to "Adobe Acrobat 10.0 Type Library" => Program Files\Adobe\Acrobat 10.0\Acrobat\acrobat.tlb
using Microsoft.Win32;

namespace PdfThumbnail.Lib
{
    public static class PdfToImage
    {
        const string AdobeObjectsErrorMessage = "Failed to create the PDF object.";
        const string BadFileErrorMessage = "Failed to open the PDF file.";
        const string ClipboardError = "Failed to get the image from clipboard.";
        const string SdkError = "This operation needs the Acrobat SDK(http://www.adobe.com/devnet/acrobat/downloads.html), which is combined with the full version of Adobe Acrobat.";

        public static byte[] PdfPageToPng(string pdfFilePath, int thumbWidth = 600, int thumbHeight = 750, int pageNumber = 0)
        {
            byte[] imageData = null;
            runJob((pdfDoc, pdfRect) =>
                {
                    imageData = pdfPageToPng(thumbWidth, thumbHeight, pageNumber, pdfDoc, pdfRect);
                }, pdfFilePath);
            return imageData;
        }

        public static void AllPdfPagesToPng(Action<byte[], int, int> dataCallback, string pdfFilePath, int thumbWidth = 600, int thumbHeight = 750)
        {
            runJob((pdfDoc, pdfRect) =>
                {
                    var numPages = pdfDoc.GetNumPages();
                    for (var pageNumber = 0; pageNumber < numPages; pageNumber++)
                    {
                        var imageData = pdfPageToPng(thumbWidth, thumbHeight, pageNumber, pdfDoc, pdfRect);
                        dataCallback(imageData, pageNumber + 1, numPages);
                    }
                }, pdfFilePath);
        }

        static void runJob(Action<CAcroPDDoc, CAcroRect> job, string pdfFilePath)
        {
            if (!File.Exists(pdfFilePath))
                throw new InvalidOperationException(BadFileErrorMessage);

            var acrobatPdfDocType = Type.GetTypeFromProgID("AcroExch.PDDoc");
            if (acrobatPdfDocType == null || !isAdobeSdkInstalled)
                throw new InvalidOperationException(SdkError);

            var pdfDoc = (CAcroPDDoc)Activator.CreateInstance(acrobatPdfDocType);
            if (pdfDoc == null)
                throw new InvalidOperationException(AdobeObjectsErrorMessage);

            var acrobatPdfRectType = Type.GetTypeFromProgID("AcroExch.Rect");
            var pdfRect = (CAcroRect)Activator.CreateInstance(acrobatPdfRectType);

            var result = pdfDoc.Open(pdfFilePath);
            if (!result)
                throw new InvalidOperationException(BadFileErrorMessage);

            job(pdfDoc, pdfRect);

            releaseComObjects(pdfDoc, pdfRect);
        }

        public static byte[] ResizeImage(this Image image, int thumbWidth, int thumbHeight)
        {
            var srcWidth = image.Width;
            var srcHeight = image.Height;
            using (var bmp = new Bitmap(thumbWidth, thumbHeight, PixelFormat.Format32bppArgb))
            {
                using (var gr = Graphics.FromImage(bmp))
                {
                    gr.SmoothingMode = SmoothingMode.HighQuality;
                    gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    gr.CompositingQuality = CompositingQuality.HighQuality;
                    gr.InterpolationMode = InterpolationMode.High;

                    var rectDestination = new Rectangle(0, 0, thumbWidth, thumbHeight);
                    gr.DrawImage(image, rectDestination, 0, 0, srcWidth, srcHeight, GraphicsUnit.Pixel);

                    using (var memStream = new MemoryStream())
                    {
                        bmp.Save(memStream, ImageFormat.Png);
                        return memStream.ToArray();
                    }
                }
            }
        }

        static bool isAdobeSdkInstalled
        {
            get
            {
                return Registry.ClassesRoot.OpenSubKey("AcroExch.PDDoc", writable: false) != null;
            }
        }

        private static Bitmap pdfPageToBitmap(int pageNumber, CAcroPDDoc pdfDoc, CAcroRect pdfRect)
        {
            var pdfPage = (CAcroPDPage)pdfDoc.AcquirePage(pageNumber);
            if (pdfPage == null)
                throw new InvalidOperationException(BadFileErrorMessage);

            var pdfPoint = (CAcroPoint)pdfPage.GetSize();

            pdfRect.Left = 0;
            pdfRect.right = pdfPoint.x;
            pdfRect.Top = 0;
            pdfRect.bottom = pdfPoint.y;

            pdfPage.CopyToClipboard(pdfRect, 0, 0, 100);

            Bitmap pdfBitmap = null;
            var thread = new Thread(() =>
            {
                var data = Clipboard.GetDataObject();
                if (data != null && data.GetDataPresent(DataFormats.Bitmap))
                    pdfBitmap = (Bitmap)data.GetData(DataFormats.Bitmap);
            });
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            thread.Join();

            Marshal.ReleaseComObject(pdfPage);

            return pdfBitmap;
        }

        private static byte[] pdfPageToPng(int thumbWidth, int thumbHeight, int pageNumber, CAcroPDDoc pdfDoc, CAcroRect pdfRect)
        {
            var pdfBitmap = pdfPageToBitmap(pageNumber, pdfDoc, pdfRect);
            if (pdfBitmap == null)
                throw new InvalidOperationException(ClipboardError);

            var pdfImage = pdfBitmap.GetThumbnailImage(thumbWidth, thumbHeight, null, IntPtr.Zero);
            // (+ 7 for template border)
            var imageData = pdfImage.ResizeImage(thumbWidth + 7, thumbHeight + 7);
            return imageData;
        }

        private static void releaseComObjects(CAcroPDDoc pdfDoc, CAcroRect pdfRect)
        {
            pdfDoc.Close();
            Marshal.ReleaseComObject(pdfRect);
            Marshal.ReleaseComObject(pdfDoc);
        }
    }
}
و برای استفاده از آن خواهیم داشت:
using System;
using System.IO;
using System.Windows.Forms;
using PdfThumbnail.Lib;

namespace PdfThumbnail
{
    class Program
    {
        static void Main(string[] args)
        {
            var pdfPath = Application.StartupPath + @"\test.pdf";
            PdfToImage.AllPdfPagesToPng((pageImageData, pageNumber, numPages) =>
                {
                    Console.WriteLine("Page {0}/{1}", pageNumber, numPages);
                    File.WriteAllBytes(string.Format("{0}\\page-{1}.png", Application.StartupPath, pageNumber), pageImageData);
                }, pdfPath);
        }
    }
}

کدهای این قسمت را از اینجا نیز می‌توانید دریافت کنید:
PdfThumbnail.zip
 
بازخوردهای پروژه‌ها
اعمال نشدن گروهبندی
با سلام. چرا گروهبندی بر روی خروجی اعمال نمی‌شود؟
کلاس هدر گزارش:
 public class CH_Rpt_Report1 : IPageHeader
    {

        public TermViewModel TermInfo { get; set; }
        public string StartDate { get; set; }
        public string EndDate { get; set; } 

        public CH_Rpt_AllTeacherAbsents(TermViewModel termInfo, string startDate, string endDate)
        {
            TermInfo = termInfo;
            StartDate = startDate;
            EndDate = endDate; 
        }
        public CH_Rpt_AllTeacherAbsents()
        {

        }
        public IPdfFont PdfRptFont { set; get; }

        public PdfGrid RenderingReportHeader(Document pdfDoc, PdfWriter pdfWriter, IList<SummaryCellData> summaryData)
        {
            var rootGrid = new PdfGrid(1);
            rootGrid.DefaultCell.BorderWidth = 0;
            rootGrid.WidthPercentage = 100;

           ...

            return grid;
        }
      
        public PdfGrid RenderingGroupHeader(Document pdfDoc, PdfWriter pdfWriter, IList<CellData> newGroupInfo, IList<SummaryCellData> summaryData)
        {
            var teacherCode = newGroupInfo.GetSafeStringValueOf<TeachersAbsentRow>(p => p.TeacherCode);
            var teacherFullName = newGroupInfo.GetSafeStringValueOf<TeachersAbsentRow>(p => p.TeacherFullName);
            var table = new PdfGrid(1)
            {
                WidthPercentage = 100,
                HorizontalAlignment = PdfWriter.RUN_DIRECTION_RTL,
                RunDirection = PdfWriter.RUN_DIRECTION_RTL
            };
            table.AddSimpleRow((cellData, cellProperties) =>
            {
                cellData.Value = (teacherFullName + " - " + teacherCode).FixWeakCharacters();
                //cellData.Value = (teacherFullName);
                cellProperties.PdfFont = FontHelper.GetIPdfFont(FontHelper.GetFontPath(FarsiFonts.BYekan), new BaseColor(Color.Gray), 12);
                cellProperties.HorizontalAlignment = HorizontalAlignment.Right;
            });

            return table.AddBorderToTable(borderColor: BaseColor.LIGHT_GRAY, spacingBefore: 5f);
        }

    }
کلاس گزارش:
public class Rpt_AllTeacherAbsents : IReportBase
    {
        #region IReportBase

        public string ReportFileName { get; set; }

        #endregion IReportBase

        #region Properties

        public bool ShowTeacherInSeperatePage { get; set; }
        public List<TeachersAbsentRow> DataSource { get; set; }
        public string StartDate { get; set; }
        public string EndDate { get; set; }
        public bool ShowFooter { get; set; }
        public TermViewModel Term { get; set; }

        #endregion Properties

        #region Constructors

        public Rpt_AllTeacherAbsents()
        {
        }

        public Rpt_AllTeacherAbsents(List<TeachersAbsentRow> dataSource, TermViewModel term, string startDate = "", string endDate = "", bool showFooter = true, bool showTeacherInSeperatePage = false)
        {
            ShowFooter = showFooter;
            DataSource = dataSource;
            Term = term;
            StartDate = startDate;
            EndDate = endDate;
            ShowTeacherInSeperatePage = showTeacherInSeperatePage;
        }

        #endregion Constructors

        public IPdfReportData Create()
        {
            return new PdfReport()
            .DocumentPreferences(doc =>
            {
                doc.RunDirection(PdfRunDirection.RightToLeft);
                doc.Orientation(PageOrientation.Landscape);
                doc.PageSize(PdfPageSize.A4);
                doc.DocumentMetadata(new DocumentMetadata
                {
                     ...
                });
            })
            .DefaultFonts(fonts =>
            {
                fonts.Size(8);
                fonts.Path(FontHelper.GetFontPath(FarsiFonts.BYekan),
                    //fonts.Path(Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\BYekan.ttf",
                 Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf");
            })
            .PagesFooter(footer =>
            {
                #region Footer

                if (ShowFooter)
                {
                    footer.XHtmlFooter(rptFooter =>
                    {
                        IPdfFont ipf = footer.PdfFont;
                        ipf.Size = 9;
                        rptFooter.PageFooterProperties(new XFooterBasicProperties
                        {
                            RunDirection = PdfRunDirection.RightToLeft,
                            ShowBorder = true,
                            PdfFont = ipf,
                            TotalPagesCountTemplateHeight = 10,
                            TotalPagesCountTemplateWidth = 50,
                            SpacingBeforeTable = 25f,
                            InlineCss = "border:0px solid;border-top:1px solid black;"
                        });
                        //RazorMachine rm = new RazorMachine();
                        rptFooter.AddPageFooter(pageFooter =>
                        {
                            return HeaderAndFooterUtility.InitCommonFooter(Term, pageFooter);
                        });
                    });
                }

                #endregion
            })
            .PagesHeader(header =>
            {
                header.CustomHeader(new CH_Rpt_AllTeacherAbsents(Term, StartDate, EndDate)
                {
                    PdfRptFont = header.PdfFont
                });
            })
            .MainTableTemplate(template =>
            {
                template.CustomTemplate(new GrayTemplate(false));
            })
            .MainTablePreferences(table =>
            {
                #region

                table.ShowHeaderRow(true);
                table.SpacingAfter(10f);
                table.ColumnsWidthsType(TableColumnWidthType.Absolute);
                table.NumberOfDataRowsPerPage(0);
                table.GroupsPreferences(new GroupsPreferences
                {
                    GroupType = GroupType.HideGroupingColumns,
                    SpacingBeforeAllGroupsSummary = 1f,
                    SpacingAfterAllGroupsSummary = 5,
                    NewGroupAvailableSpacingThreshold = 30,
                    RepeatHeaderRowPerGroup = true,
                    ShowOneGroupPerPage = ShowTeacherInSeperatePage,
                });

                #endregion
            })
            .MainTableDataSource(dataSource =>
            {
                dataSource.StronglyTypedList<TeachersAbsentRow>(DataSource);
            })
            .MainTableSummarySettings(summarySettings =>
            {
                //summarySettings.OverallSummarySettings("جمع ساعات تدریس : ");
                // summarySettings.PreviousPageSummarySettings("Previous Page Summary");
                // summarySettings.PageSummarySettings("Page Summary");
            })
            .MainTableColumns(columns =>
            {
                #region Columns

                columns.AddColumn(column =>
                {
                    column.PropertyName("rowNo");
                    column.IsRowNumber(true);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Center);
                    column.IsVisible(true);
                    column.Order(0);
                    column.Width(40);
                    column.HeaderCell("#", horizontalAlignment: HorizontalAlignment.Center);
                });
                columns.AddColumn(column =>
                {
                    column.PropertyName<TeachersAbsentRow>(x => x.TeacherCode);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Center);
                    column.IsVisible(true);
                    column.Order(2);
                    column.Width(100);
                    column.HeaderCell("کد استاد", horizontalAlignment: HorizontalAlignment.Right);
                    column.Group(true, (val1, val2) =>
                    {
                        return val1.ToString() == val2.ToString();
                    });
                });
                
                columns.AddColumn(column =>
                {
                    column.PropertyName<TeachersAbsentRow>(x => x.LessonCode);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Left);
                    column.IsVisible(true);
                    column.Order(2);
                    column.Width(100);
                    column.HeaderCell("کد درس", horizontalAlignment: HorizontalAlignment.Center);
                });
                columns.AddColumn(column =>
                {
                    column.PropertyName<TeachersAbsentRow>(x => x.LessonName);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Center);
                    column.IsVisible(true);
                    column.Order(2);
                    column.Width(200);
                    column.HeaderCell("نام درس", horizontalAlignment: HorizontalAlignment.Center);
                });
                columns.AddColumn(column =>
                {
                    column.PropertyName<TeachersAbsentRow>(x => x.Date);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Center);
                    column.IsVisible(true);
                    column.Order(2);
                    column.Width(90);
                    column.HeaderCell("تاریخ", horizontalAlignment: HorizontalAlignment.Center);
                });
                columns.AddColumn(column =>
                {
                    column.PropertyName<TeachersAbsentRow>(x => x.StartTimeToEndTime);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Center);
                    column.IsVisible(true);
                    column.Order(2);
                    column.Width(120);
                    column.HeaderCell("ساعت", horizontalAlignment: HorizontalAlignment.Center);
                });
                columns.AddColumn(column =>
                {
                    column.PropertyName<TeachersAbsentRow>(x => x.TrendCode);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Center);
                    column.IsVisible(true);
                    column.Order(2);
                    column.Width(90);
                    column.HeaderCell("کد رشته", horizontalAlignment: HorizontalAlignment.Center);
                });
                columns.AddColumn(column =>
                {
                    column.PropertyName<TeachersAbsentRow>(x => x.TrendName);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Center);
                    column.IsVisible(true);
                    column.Order(2);
                    column.Width(180);
                    column.HeaderCell("عنوان رشته", horizontalAlignment: HorizontalAlignment.Center);
                });
                columns.AddColumn(column =>
                {
                    column.PropertyName<TeachersAbsentRow>(x => x.PlaceFullName);
                    column.CellsHorizontalAlignment(HorizontalAlignment.Center);
                    column.IsVisible(true);
                    column.Order(2);
                    column.Width(130);
                    column.HeaderCell("مکان برگزاری", horizontalAlignment: HorizontalAlignment.Center);
                });

                #endregion
            })
            .MainTableEvents(events =>
            {
                #region Events

                #region Alternate Row Colors

                events.CellCreated(args =>
                {
                     
                });

                #endregion


                events.DataSourceIsEmpty(message: "داده ای برای مشاهده وجود ندارد.");
                events.CellCreated(args =>
                {
                    if (args.RowType == RowType.DataTableRow)
                    {

                    }
                });

                #endregion
            })
            .Export(export =>
            {

            })
            .Generate(data => data.AsPdfFile(ReportFileName));
        }

    }
مدل هم بصورت زیر است:
public class TeachersAbsentRow
    {
        public TeachersAbsentRow()
        {
            
        }
        public int Id { get; set; }
        public int ProgramId { get; set; }
        public string RowNumber { get; set; }
        public bool IsSelected { get; set; }


        public int TeacherId { get; set; }
        public string TeacherCode { get; set; }
        public string TeacherFullName { get; set; }
        public string TeacherFirstName { get; set; }
        public string TeacherLastName { get; set; }

        public string GroupNumber { get; set; }
        public string GroupDescription { get; set; }

        public string LessonId { get; set; }
        public string LessonCode { get; set; }
        public string LessonName { get; set; }
        public int LessonPresentationTerm { get; set; }

        public string TrendId { get; set; }
        public string TrendCode { get; set; }
        public string TrendName { get; set; }

        public string Date { get; set; }
        public string StartTime { get; set; }
        public string EndTime { get; set; }

        public string StartTimeToEndTime { get; set; }
        public string DayNumber { get; set; }
        public string DayTitle { get; set; }

        public int BuildingId { get; set; }
        public int PlaceId { get; set; }
        public string PlaceName { get; set; }
        public string BuildingName { get; set; }
        public string PlaceFullName { get; set; }
    }

مطالب
تزریق وابستگی‌های Automapper به کمک Autofac
در این مقاله قصد دارم به وسیله Autofac تزریق وابستگی‌های Automapper و همچنین Register کردن فایل‌های Profile Mapper را توضیح دهم.
حتما مقالات مقالات متعدد در رابطه با تزریق وابستگی را که در این سایت وجود دارند، مطالعه کرده‌اید. در این بخش قصد دارم از Autofac (بجای StructureMap) برای تزریق Automapper استفاده کنم.
1. ابتدا ساختار پروژه را بررسی می‌کنیم. بدین منظور یک پروژه جدید را با عنوان AufacDI ایجاد میکنیم. 
2. در این مرحله یک پروژه از نوع Class Library را با عنوان AufacDI.DomainClasses، برای شبیه سازی مدل ایجاد میکنیم. 
3. سپس یک پروژه از نوع Class Library را با عنوان AufacDI.IocConfig برای تعریف تنظیمات تزریق وابستگی ایجاد میکنیم.
4. در ادامه، پروژه‌ای را از نوع Class Library با عنوان AufacDI.MapperProfile برای معرفی Profile‌های Mapper ایجاد میکنیم.
5. همچنین پروژه‌ای را برای ViewModel‌ها تعریف میکنیم؛ با عنوان AufacDI.ViewModel. 
6. و در آخر ایجاد پروژه‌ای برای بخش UI با عنوانAufacDI.WebApplication

در ابتدا نیاز است که بسته‌های زیر را از Nuget دریافت و  نصب کنیم:
PM>Install-Package Autofac
PM>Install-Package Autofac.Mvc5
PM>Install-Package AutoMapper
بسته Autofac را در لایه AufacDI.IocConfig و AufacDI.ConsoleApplication نصب می‌کنیم.
بسته Install-Package Autofac.Mvc5  را برای تزریق وابستگی‌ها در لایه UI استفاده میکنیم.
و بسته AutoMapper را در لایه AufacDI.MapperProfile , AufacDI.IocConfig و  AufacDI.WebApplication  نصب میکنیم (به دلیل اینکه این پروژه برای مثال، Automapper به لایه UI اضافه شده است وگرنه باید در لایه Service ارجاع داده شود).

حال در این بخش به تعاریف داخلی پروژه می‌پردازیم:
لازم است ابتدا یک Domain Class را تعریف کنیم؛ به صورت زیر:
namespace AufacDI.DomainClasses
{
    public class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}
سپس ViewModel متناظر با آن را تعریف میکنیم:
namespace AufacDI.ViewModel
{
    public class CategoryViewModel
    {
        public int Id { get; set; }
        public int Name { get; set; }
    }
}
سپس یک  Profile را برای مدل نمونه تعریف میکینم. (ارجاعات لازم به DomainClasses و ViewModel داده شود)
using AufacDI.DomainClasses;
using AufacDI.ViewModel;
using AutoMapper;

namespace AufacDI.MapperProfile
{
    public class CategoryProfile : Profile
    {
        public CategoryProfile()
        {
            CreateMap<Category, CategoryViewModel>();
            CreateMap<CategoryViewModel, Category>();
        }
    }
}

حال به بخش اصلی میرسیم؛ یعنی تکمیل بخش IocConfig: (ارجاعات لازم به MapperProfile داده شود)
using AufacDI.MapperProfile;
using Autofac;
using AutoMapper;
using System;
using System.Linq;

namespace AufacDI.IocConfig
{
    public static class IoCContainer
    {
       public static void Register(ContainerBuilder builder)
        {
            // شناسایی پروفایل‌ها براساس نمونه از کلاس پر.وفایل 
            var profiles = from types in typeof(CategoryProfile).Assembly.GetTypes()
                           where typeof(Profile).IsAssignableFrom(types)
                           select (Profile)Activator.CreateInstance(types);

            // رجیستر کردن کلاس‌های پروفایل در اتومپر
            builder.Register(ctx => new MapperConfiguration(cfg =>
            {
                foreach (var profile in profiles)
                    cfg.AddProfile(profile);
            })).SingleInstance().AutoActivate().AsSelf();

            // رجیستر کردن کلاس  MapperConfiguration و ایجاد آن براساس IMapper
            builder.Register(ctx => ctx.Resolve<MapperConfiguration>().CreateMapper()).As<IMapper>().InstancePerRequest();
        }
    }
}

در ادامه با یک مثال، روند کلی را توضیح میدهیم:
            var builder = new ContainerBuilder();

            // تزریق کنترلرها برای تزریف سایر المان‌ها در سازنده
            builder.RegisterControllers(typeof(MvcApplication).Assembly).InstancePerDependency();

            // فراخوانی متد رجیستر برای تزریق وابستگی مپر و کلاس‌های پروفایل آن
            IoCContainer.Register(builder);

            // ایجاد نمونه از سازنده
            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
این بخش، معرفی و تعریف نگاشت‌های تزریق وابستگی می‌باشد.
نمونه‌ای از پیاده سازی در سطح کنترلر
namespace AufacDI.WebApplication.Controllers
{
    public class HomeController : Controller
    {
        private readonly IMapper _mapepr;
        public HomeController(IMapper mapepr)
        {
            _mapepr = mapepr;
        }

        public ActionResult Index()
        {
            // مپ کردن یک کلاس به یک کلاس
            var categoryViewModel = new CategoryViewModel { Id = 1, Name = "News" };
            var categoryModel = _mapepr.Map<CategoryViewModel, Category>(categoryViewModel);

            // مپ کردن لیست از کلاس به لیستی از کلاس
            var categoryListModel = new List<Category>();
            categoryListModel.Add(new Category { Id = 1, Name = "A" });
            categoryListModel.Add(new Category { Id = 2, Name = "B" });
            categoryListModel.Add(new Category { Id = 3, Name = "C" });
            categoryListModel.Add(new Category { Id = 4, Name = "D" });
            categoryListModel.Add(new Category { Id = 5, Name = "E" });

            var categoryListViewModel = categoryListModel.AsQueryable().ProjectTo<CategoryViewModel>(_mapepr.ConfigurationProvider).ToList(); ;

            return View();
        }
    }
}
نکته: برای مپ کردن یک آبجکت به آبجکتی دیگر، از متد Map استفاده می‌شود و برای مپ کردن لیستی از آبجکت‌ها از ProjectTo استفاده می‌شود.
نمونه ای از مثال AufacDI.rar
مطالب
خلاصه اشتراک‌های روز دو شنبه 1390/06/28