من فایل رو از روی آخرین کامنت شما برداشتم و عینا اجرا کردم. بعد از Login همه چیز خوب کار میکند تا وقتی که به قسمت Manage منتقل شویم. مثلا برای تایید email یا تایید شماره تلفن. بعد از اینکه هر کدام از این کارها انجام شود، برای هر Viewای که Controller آن به صفت [Authorize] مزین شده باشد، ابتدا به صفحهی Login هدایت میشود. آیا این رفتار طبیعیست یا چیزی از قلم افتاده؟
نظرات مطالب
دریافت خروجی سایت
- پیش نمایش آن به این صورت است: نسخه چاپی ذیل هر مطلب را تهیه کنید. همانند آن در فایل نهایی قرار گرفته.
- رنگ زمینه صفحات فایلهای PDF مرسوم نیست مشکی باشد. من ندیدم تا بحال. فایل تولیدی برای چاپ بهینه سازی شده است. قلم آن هم از نوعی انتخاب شده تا در اندازه کوچک خوانا باشد.
- رنگ زمینه صفحات فایلهای PDF مرسوم نیست مشکی باشد. من ندیدم تا بحال. فایل تولیدی برای چاپ بهینه سازی شده است. قلم آن هم از نوعی انتخاب شده تا در اندازه کوچک خوانا باشد.
نظرات مطالب
استفاده از reCAPTCHA در ASP.NET
این مورد بیشتر به تداخل css کلی سایت با این کنترل مربوط میشود. بهترین کار استفاده از firebug است. ابتدا در برگه net آن بررسی کنید پیام 404 ایی مشاهده میشود؟ ممکن است چیزی از قلم افتاده باشد. سپس به وسیله firebug به صورت live شروع به ویرایش css المان انتخاب شده کنید تا به نتیجه برسید.
پاسخ به بازخوردهای پروژهها
خطا و راهنمایی
یک نکته تکمیلی:
ارجاعی را به اسمبلی «System.Windows.Forms.DataVisualization.dll» که در پوشه bin در ریشه اصلی سورسها هست اضافه کنید. این مورد در مثالهای برنامه نیاز است.
فایل xml ایی که از قلم افتاده است پیوست شد. بعدا به سورسها اضافه خواهم کرد:
AppManifest.xml
پ.ن.
آخرین سورس را دریافت کنید. این تغییرات به آن نیز اعمال شد.
ارجاعی را به اسمبلی «System.Windows.Forms.DataVisualization.dll» که در پوشه bin در ریشه اصلی سورسها هست اضافه کنید. این مورد در مثالهای برنامه نیاز است.
فایل xml ایی که از قلم افتاده است پیوست شد. بعدا به سورسها اضافه خواهم کرد:
AppManifest.xml
پ.ن.
آخرین سورس را دریافت کنید. این تغییرات به آن نیز اعمال شد.
اکثر خزندهها با آدرسهای فارسی مشکل دارند. اگر لاگهای خطای سرور رو بررسی کنید عموما عاجزند از درک encoding این نوع urlها و مدام به خطای 404 برخورد میکنند. برای نمونه این تصویر خروجی یکی از همین خزندههایی است که سایت را برای بودن آدرس یا جستجوی خاصی در سایت مدام چک میکند. به نظر Bing است.
بنابراین آدرس شما باید چند قسمتی باشد؛ اگر عبارت فارسی یا یونیکد قرار است در آن درج شود. قسمت ابتدایی آن باید به نحوی انگلیسی باشد و قسمت نهایی آن فارسی و این قسمت فارسی باید در کار مسیریابی بیاهمیت باشد تا اگر خزنده در تفسیر آن اشتباه کرد، به خطای 404 برخورد نکند.
صورت مساله:
- میخواهیم footer پیش فرض PdfReport را که تاریخ را در یک سمت، و شماره صفحه را در سمتی دیگر نمایش میدهد، به عبارت «صفحه x از n» تغییر دهیم.
- میخواهیم در Header گزارش بجای Header پیش فرض PdfReport یکی از قالبهای PDF تهیه شده توسط Open Office را نمایش دهیم (و یا هر ساختار دیگری را).
تمام اجزای PdfReport جهت امکان اعمال تغییرات کلی و توسعه آنها طراحی شدهاند؛ قالبها، هدر، فوتر، منابع داده، قالبهای نمایش سلولها، تعریف توابع تجمعی سفارشی و غیره. جهت سهولت کار، به ازای هر یک از این موارد، پیاده سازیهای پیش فرضی در PdfReport قرار دارند، امکان اگر مورد رضایت شما نیستند ... از بنیان تغییرشان دهید! (و همچنین اگر مورد جالبی را پیاده سازی کردید، میتوانید به عنوان یک وصله جدید ارائه دهید تا به پروژه اضافه شود)
ضمنا این مطالب سفارشی سازی نیاز به آشنایی با ساختار iTextSharp را نیز دارند؛ در حد ایجاد یک جدول ساده باید با iTextSharp آشنا باشید.
مدلهای مورد استفاده:
توسط این مدلها قصد داریم تعدادی فعالیت (Task) را که به تعدادی کاربر انتساب یافته است، نمایش دهیم. همچنین نمایش مقادیر خواص تو در تو نیز در اینجا مد نظر است؛ برای مثال ستونی مانند این:
کدهای کامل مثال را در ادامه ملاحظه خواهید نمود:
به همراه Header سفارشی:
و Footer سفارشی استفاده شده:
البته لازم به ذکر است که تمام این کدها به پوشه Samples سورس پروژه نیز جهت سهولت دسترسی، اضافه شدهاند .
توضیحات:
برای پیاده سازی Header و Footer سفارشی در PdfReport نیاز خواهید داشت تا دو اینترفیس IPageHeader و IPageFooter را پیاده سازی کنید.
ساختار IPageHeader را در ذیل ملاحظه میکنید:
RenderingGroupHeader مرتبط است به مباحث گروه بندی اطلاعات و گزارشات master-detail که در قسمتهای بعد به آنها اشاره خواهد شد. چون در اینجا به آن نیازی نداشتیم، تنها کافی است متد متناظر با آن، null بر گرداند که در کلاس CustomHeader فوق قابل مشاهده است.
متد RenderingReportHeader به ازای تولید هر صفحه جدید، فراخوانی خواهد شد. به عبارتی میتوانید در صفحات مختلف، هدرهای مختلفی را نمایش دهید.
خروجی هر دو متد در اینجا یک جدول از نوع PdfPTable است. بنابراین هر نوع ساختار دلخواهی را که علاقمند هستید به شکل یک PdfPTable ایجاد کرده و بازگشت دهید. این جدول در هدر صفحات ظاهر خواهد شد.
برای نمونه در کلاس CustomHeader، یک قالب تهیه شده توسط Open Office توسط متد توکار PdfImageHelper.GetITextSharpImageFromPdfTemplate دریافت و تبدیل به تصویر میشود. این تصویر از نوع تصاویر قابل درک توسط iTextSharp است و نه اینکه واقعا تبدیل به یک تصویر معمولی مثلا از نوع bmp شود. سپس این تصویر، در یک ردیف از جدولی قرار داده شده و این جدول بازگشت داده میشود.
در کل یا توسط کار با PdfPTable میتوانید یک هدر غیرپیش فرض را طراحی کنید و یا میتوانید توسط ابزارهای بصری مانند Open Office یک قالب خاص را برای آن تهیه کرده و به روشی که ذکر شد و کدهای آنرا ملاحظه میکنید، بارگذاری و استفاده کنید. این قالبها در مسیر Bin\Data سورسهای پروژه قرار داده شدهاند.
ساختار IPageFooter به صورت زیر است:
برای طراحی یک Footer سفارشی کافی است اینترفیس فوق را پیاده سازی کنید که نمونهای از آنرا در کدهای کلاس CustomFooter ملاحظه مینمائید.
متد DocumentOpened، با وهله سازی شیء Document فراخوانی میشود.
متد PageFinished هر بار پیش از اتمام کار صفحه جاری و افزوده شدن آن به Document فراخوانی میگردد.
متد ClosingDocument، در زمان بسته شدن شیء Document فراخوانی خواهد شد.
اگر به امضای این متدها دقت کنید، شیء PdfWriter در اختیار شما قرار گرفته است که توسط آن میتوان مستقیما بر روی فایل PDF، محتوایی را قرار داد. شیء Document نیز در دسترس است. مثلا توسط آن میتوان اندازه دقیق صفحه را بدست آورد.
به علاوه پارامتر columnCellsSummaryData نیز امکان دسترسی به مقادیر ردیفهای قبلی را در اختیار شما قرار میدهد. برای مثال اگر نیاز دارید تا بر اساس مقادیر ستونها و ردیفهای قبلی، محاسباتی را انجام داده و در پایین صفحات درج کنید، به این ترتیب دسترسی کاملی به آنها، خواهید داشت.
استفاده از این کلاسهای سفارشی نیز همواره به شکل زیر خواهد بود:
کلا در PdfReport هر جایی متدی به نام CustomXYZ را مشاهده کردید، این متد یک اینترفیس را دریافت میکند. به عبارتی این امکان را خواهید داشت تا از متدهای پیش فرض مهیا صرفنظر کرده و مطابق نیاز، نسبت به پیاده سازی و استفاده از وهله جدیدی از این اینترفیس تعریف شده، اقدام کنید.
- میخواهیم footer پیش فرض PdfReport را که تاریخ را در یک سمت، و شماره صفحه را در سمتی دیگر نمایش میدهد، به عبارت «صفحه x از n» تغییر دهیم.
- میخواهیم در Header گزارش بجای Header پیش فرض PdfReport یکی از قالبهای PDF تهیه شده توسط Open Office را نمایش دهیم (و یا هر ساختار دیگری را).
تمام اجزای PdfReport جهت امکان اعمال تغییرات کلی و توسعه آنها طراحی شدهاند؛ قالبها، هدر، فوتر، منابع داده، قالبهای نمایش سلولها، تعریف توابع تجمعی سفارشی و غیره. جهت سهولت کار، به ازای هر یک از این موارد، پیاده سازیهای پیش فرضی در PdfReport قرار دارند، امکان اگر مورد رضایت شما نیستند ... از بنیان تغییرشان دهید! (و همچنین اگر مورد جالبی را پیاده سازی کردید، میتوانید به عنوان یک وصله جدید ارائه دهید تا به پروژه اضافه شود)
ضمنا این مطالب سفارشی سازی نیاز به آشنایی با ساختار iTextSharp را نیز دارند؛ در حد ایجاد یک جدول ساده باید با iTextSharp آشنا باشید.
مدلهای مورد استفاده:
namespace PdfReportSamples.Models { public class Task { public int Id { set; get; } public string Name { set; get; } public int PercentCompleted { set; get; } public bool IsActive { set; get; } public User Assignee { set; get; } } }
using System; namespace PdfReportSamples.Models { public class User { public int Id { set; get; } public string Name { set; get; } public string LastName { set; get; } public long Balance { set; get; } public DateTime RegisterDate { set; get; } } }
column.PropertyName<Task>(x => x.Assignee.Name)
using System; using System.Collections.Generic; using System.Drawing; using PdfReportSamples.Models; using PdfRpt.Core.Contracts; using PdfRpt.FluentInterface; namespace PdfReportSamples.CustomHeaderFooter { public class CustomHeaderFooterPdfReport { readonly CustomHeader _customHeader = new CustomHeader(); public IPdfReportData CreatePdfReport() { return new PdfReport().DocumentPreferences(doc => { doc.RunDirection(PdfRunDirection.LeftToRight); 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(Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\tahoma.ttf", Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\verdana.ttf"); }) .PagesFooter(footer => { footer.CustomFooter(new CustomFooter(footer.PdfFont, PdfRunDirection.LeftToRight)); }) .PagesHeader(header => { header.CustomHeader(_customHeader); }) .MainTableTemplate(template => { template.BasicTemplate(BasicTemplate.SilverTemplate); }) .MainTablePreferences(table => { table.ColumnsWidthsType(TableColumnWidthType.Relative); table.MultipleColumnsPerPage(new MultipleColumnsPerPage { ColumnsGap = 22, ColumnsPerPage = 2, ColumnsWidth = 250, IsRightToLeft = false, TopMargin = 7 }); }) .MainTableDataSource(dataSource => { var rows = new List<Task>(); var rnd = new Random(); for (int i = 1; i < 210; i++) { rows.Add(new Task { Assignee = new User { Id = i, Name = "user-" + i }, IsActive = rnd.Next(0, 2) == 1 ? true : false, Name = "task-" + i }); } dataSource.StronglyTypedList(rows); }) .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<Task>(x => x.Name); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(1); column.Width(3); column.HeaderCell("Task Name"); }); columns.AddColumn(column => { column.PropertyName<Task>(x => x.Assignee.Name); // nested property support column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(2); column.Width(3); column.HeaderCell("Assignee"); }); columns.AddColumn(column => { column.PropertyName<Task>(x => x.IsActive); column.CellsHorizontalAlignment(HorizontalAlignment.Center); column.IsVisible(true); column.Order(3); column.Width(2); column.HeaderCell("Active"); column.ColumnItemsTemplate(template => { template.Checkmark(checkmarkFillColor: Color.Green, crossSignFillColor: Color.DarkRed); }); }); }) .MainTableEvents(events => { events.DataSourceIsEmpty(message: "There is no data available to display."); }) .Export(export => { export.ToExcel(); }) .Generate(data => data.AsPdfFile(AppPath.ApplicationPath + "\\Pdf\\CustomHeaderFooterPdfReportSample.pdf")); } } }
به همراه Header سفارشی:
using System.Collections.Generic; using iTextSharp.text; using iTextSharp.text.pdf; using PdfRpt.Core.Contracts; using PdfRpt.Core.Helper; namespace PdfReportSamples.CustomHeaderFooter { public class CustomHeader : IPageHeader { public PdfPTable RenderingGroupHeader(Document pdfDoc, PdfWriter pdfWriter, IList<CellData> rowdata, IList<SummaryCellData> summaryData) { return null; } Image _image; public PdfPTable RenderingReportHeader(Document pdfDoc, PdfWriter pdfWriter, IList<SummaryCellData> summaryData) { if (_image == null) //cache is empty { var templatePath = AppPath.ApplicationPath + "\\data\\PdfHeaderTemplate.pdf"; _image = PdfImageHelper.GetITextSharpImageFromPdfTemplate(pdfWriter, templatePath); } var table = new PdfPTable(1); var cell = new PdfPCell(_image, true) { Border = 0 }; table.AddCell(cell); return table; } } }
و Footer سفارشی استفاده شده:
using System.Collections.Generic; using iTextSharp.text; using iTextSharp.text.pdf; using PdfRpt.Core.Contracts; namespace PdfReportSamples.CustomHeaderFooter { public class CustomFooter : IPageFooter { PdfContentByte _pdfContentByte; readonly IPdfFont _pdfRptFont; readonly Font _font; readonly PdfRunDirection _direction; PdfTemplate _template; public CustomFooter(IPdfFont pdfRptFont, PdfRunDirection direction) { _direction = direction; _pdfRptFont = pdfRptFont; _font = _pdfRptFont.Fonts[0]; } public void ClosingDocument(PdfWriter writer, Document document, IList<SummaryCellData> columnCellsSummaryData) { _template.BeginText(); _template.SetFontAndSize(_pdfRptFont.Fonts[0].BaseFont, 8); _template.SetTextMatrix(0, 0); _template.ShowText((writer.PageNumber - 1).ToString()); _template.EndText(); } public void PageFinished(PdfWriter writer, Document document, IList<SummaryCellData> columnCellsSummaryData) { var pageSize = document.PageSize; var text = "Page " + writer.PageNumber + " / "; var textLen = _font.BaseFont.GetWidthPoint(text, _font.Size); var center = (pageSize.Left + pageSize.Right) / 2; var align = _direction == PdfRunDirection.RightToLeft ? Element.ALIGN_RIGHT : Element.ALIGN_LEFT; ColumnText.ShowTextAligned( canvas: _pdfContentByte, alignment: align, phrase: new Phrase(text, _font), x: center, y: pageSize.GetBottom(25), rotation: 0, runDirection: (int)_direction, arabicOptions: 0); var x = _direction == PdfRunDirection.RightToLeft ? center - textLen : center + textLen; _pdfContentByte.AddTemplate(_template, x, pageSize.GetBottom(25)); } public void DocumentOpened(PdfWriter writer, IList<SummaryCellData> columnCellsSummaryData) { _pdfContentByte = writer.DirectContent; _template = _pdfContentByte.CreateTemplate(50, 50); } } }
البته لازم به ذکر است که تمام این کدها به پوشه Samples سورس پروژه نیز جهت سهولت دسترسی، اضافه شدهاند .
توضیحات:
برای پیاده سازی Header و Footer سفارشی در PdfReport نیاز خواهید داشت تا دو اینترفیس IPageHeader و IPageFooter را پیاده سازی کنید.
ساختار IPageHeader را در ذیل ملاحظه میکنید:
using System.Collections.Generic; using iTextSharp.text; using iTextSharp.text.pdf; namespace PdfRpt.Core.Contracts { public interface IPageHeader { PdfPTable RenderingGroupHeader(Document pdfDoc, PdfWriter pdfWriter, IList<CellData> newGroupInfo, IList<SummaryCellData> summaryData); PdfPTable RenderingReportHeader(Document pdfDoc, PdfWriter pdfWriter, IList<SummaryCellData> summaryData); } }
RenderingGroupHeader مرتبط است به مباحث گروه بندی اطلاعات و گزارشات master-detail که در قسمتهای بعد به آنها اشاره خواهد شد. چون در اینجا به آن نیازی نداشتیم، تنها کافی است متد متناظر با آن، null بر گرداند که در کلاس CustomHeader فوق قابل مشاهده است.
متد RenderingReportHeader به ازای تولید هر صفحه جدید، فراخوانی خواهد شد. به عبارتی میتوانید در صفحات مختلف، هدرهای مختلفی را نمایش دهید.
خروجی هر دو متد در اینجا یک جدول از نوع PdfPTable است. بنابراین هر نوع ساختار دلخواهی را که علاقمند هستید به شکل یک PdfPTable ایجاد کرده و بازگشت دهید. این جدول در هدر صفحات ظاهر خواهد شد.
برای نمونه در کلاس CustomHeader، یک قالب تهیه شده توسط Open Office توسط متد توکار PdfImageHelper.GetITextSharpImageFromPdfTemplate دریافت و تبدیل به تصویر میشود. این تصویر از نوع تصاویر قابل درک توسط iTextSharp است و نه اینکه واقعا تبدیل به یک تصویر معمولی مثلا از نوع bmp شود. سپس این تصویر، در یک ردیف از جدولی قرار داده شده و این جدول بازگشت داده میشود.
در کل یا توسط کار با PdfPTable میتوانید یک هدر غیرپیش فرض را طراحی کنید و یا میتوانید توسط ابزارهای بصری مانند Open Office یک قالب خاص را برای آن تهیه کرده و به روشی که ذکر شد و کدهای آنرا ملاحظه میکنید، بارگذاری و استفاده کنید. این قالبها در مسیر Bin\Data سورسهای پروژه قرار داده شدهاند.
ساختار IPageFooter به صورت زیر است:
using iTextSharp.text; using iTextSharp.text.pdf; using System.Collections.Generic; namespace PdfRpt.Core.Contracts { public interface IPageFooter { void DocumentOpened(PdfWriter writer, IList<SummaryCellData> columnCellsSummaryData); void PageFinished(PdfWriter writer, Document document, IList<SummaryCellData> columnCellsSummaryData); void ClosingDocument(PdfWriter writer, Document document, IList<SummaryCellData> columnCellsSummaryData); } }
برای طراحی یک Footer سفارشی کافی است اینترفیس فوق را پیاده سازی کنید که نمونهای از آنرا در کدهای کلاس CustomFooter ملاحظه مینمائید.
متد DocumentOpened، با وهله سازی شیء Document فراخوانی میشود.
متد PageFinished هر بار پیش از اتمام کار صفحه جاری و افزوده شدن آن به Document فراخوانی میگردد.
متد ClosingDocument، در زمان بسته شدن شیء Document فراخوانی خواهد شد.
اگر به امضای این متدها دقت کنید، شیء PdfWriter در اختیار شما قرار گرفته است که توسط آن میتوان مستقیما بر روی فایل PDF، محتوایی را قرار داد. شیء Document نیز در دسترس است. مثلا توسط آن میتوان اندازه دقیق صفحه را بدست آورد.
به علاوه پارامتر columnCellsSummaryData نیز امکان دسترسی به مقادیر ردیفهای قبلی را در اختیار شما قرار میدهد. برای مثال اگر نیاز دارید تا بر اساس مقادیر ستونها و ردیفهای قبلی، محاسباتی را انجام داده و در پایین صفحات درج کنید، به این ترتیب دسترسی کاملی به آنها، خواهید داشت.
استفاده از این کلاسهای سفارشی نیز همواره به شکل زیر خواهد بود:
readonly CustomHeader _customHeader = new CustomHeader(); //... .PagesFooter(footer => { footer.CustomFooter(new CustomFooter(footer.PdfFont, PdfRunDirection.LeftToRight)); }) .PagesHeader(header => { header.CustomHeader(_customHeader); })
دو مورد تکمیلی:
- کار این چرخاندنها توسط دو کلاس ArabicLigaturizer و BidiLine در iTextSharp انجام میشود. سورس کتابخانه را دریافت و این دو کلاس را مطالعه کنید (ضمن اینکه PDF های فارسی هم وجود دارند که اصلا با این الگویتمها تهیه نشدهاند و خلاصه راه سختی را پیش رو دارید).iTextSharp انجمنی نداره ولی یک mailing list فعال داره: https://lists.sourceforge.net/lists/listinfo/itext-questions
- کار این چرخاندنها توسط دو کلاس ArabicLigaturizer و BidiLine در iTextSharp انجام میشود. سورس کتابخانه را دریافت و این دو کلاس را مطالعه کنید (ضمن اینکه PDF های فارسی هم وجود دارند که اصلا با این الگویتمها تهیه نشدهاند و خلاصه راه سختی را پیش رو دارید).iTextSharp انجمنی نداره ولی یک mailing list فعال داره: https://lists.sourceforge.net/lists/listinfo/itext-questions
دو مورد تکمیلی:
- کار این چرخاندنها توسط دو کلاس ArabicLigaturizer و BidiLine در iTextSharp انجام میشود. سورس کتابخانه را دریافت و این دو کلاس را مطالعه کنید (ضمن اینکه PDF های فارسی هم وجود دارند که اصلا با این الگویتمها تهیه نشدهاند و خلاصه راه سختی را پیش رو دارید).iTextSharp انجمنی نداره ولی یک mailing list فعال داره: https://lists.sourceforge.net/lists/listinfo/itext-questions
- کار این چرخاندنها توسط دو کلاس ArabicLigaturizer و BidiLine در iTextSharp انجام میشود. سورس کتابخانه را دریافت و این دو کلاس را مطالعه کنید (ضمن اینکه PDF های فارسی هم وجود دارند که اصلا با این الگویتمها تهیه نشدهاند و خلاصه راه سختی را پیش رو دارید).iTextSharp انجمنی نداره ولی یک mailing list فعال داره: https://lists.sourceforge.net/lists/listinfo/itext-questions
معرفی HTML Helpers
در صورتی که در مورد Helperها در ASP.NET MVC اطلاعات بیشتری نیاز دارید پیشنهاد میکنم ابتدا این مطلب + را مطالعه کنید.ایجاد یک HTML Helper سفارشی برای نمایش ویدئوهای سایت آپارات
قبل از ایجاد هر Helper ی باید با خروجی نهایی آن آشنا بود. پس از بررسی خروجی نهایی کافیست بخش هایی از آن را Optional کنیم تا در زمان استفاده از آن، نسبت به مقادیر این دسته از پارامترها تصمیم گیری کنیم.
سایت آپارات نمونهی فارسی سایت YouTube است و امکان اشتراک گذاری فایلهای ویدئویی را برای کاربران مهیا کرده است. در این سایت در صفحه نمایش هر ویدئو، بخشی با عنوان "دریافت کد ویدئو" وجود دارد. با کمی بررسی در کدهای نهایی ایجاد شده توسط دستورات ذکر شده در این بخش، کد نهایی برای نمایش یک ویدئو به صورت زیر خواهد بود:
<embed height="400" width="500" flashvars="config=http://www.aparat.com//video/video/config/videohash/BA9Md/watchtype/embed" allowfullscreen="true" quality="high" name="aparattv_BA9Md" id="aparattv_BA9Md" src="http://host10.aparat.com/public/player/aparattv" type="application/x-shockwave-flash">
برای تولید پویای این کد Helper زیر میتواند مفید باشد:
using System.Web.Mvc; namespace MvcApplication1 { public static class AparatPlayerHelper { public static MvcHtmlString AparatPlayer(this HtmlHelper helper, string mediafile, int height, int width) { var player = @"<embed height=""{0}"" width=""{1}"" flashvars=""config=http://www.aparat.com//video/video/config/videohash/{2}/watchtype/embed"" allowfullscreen=""true"" quality=""high"" name=""aparattv_{2}"" id=""aparattv_{2}"""" src=""http://host10.aparat.com/public/player/aparattv"" type=""application/x-shockwave-flash"">"; player = string.Format(player, height, width, mediafile); return new MvcHtmlString(player); } } }
نحوه استفاده از این Helper:
@Html.AparatPlayer("BA9Md", 400, 500)
اگر به آدرس صفحات در سایت آپارات دقت کنید URL جاری به یک عبارت چند حرقی ختم میشود که از این عبارت به عنوان مقدار پارامتر mediafile و شناسه منحصر بفرد فایل ویدئو استفاده شده است.
ایجاد Helper سفارشی جهت نمایش ویدئوهای YouTube:
با توجه به توضیحات فوق یک Helper سفارشی برای نمایش ویدئوهای YouTube بصورت زیر است:
using System; using System.Drawing; using System.Web.Mvc; namespace MvcApplication1 { public static class YouTubePlayerHelper { public static MvcHtmlString YouTubePlayer(this HtmlHelper helper, string playerId, string mediaFile, YouTubePlayerOption youtubePlayerOption) { const string baseURL = "http://www.youtube.com/v/"; // YouTube Embedded Code var player = @"<div id=""YouTubePlayer_{7}""width:{1}px; height:{2}px;""> <object width=""{1}"" height=""{2}""> <param name=""movie"" value=""{6}{0}&fs=1&border={3}&color1={4}&color2={5}""></param> <param name=""allowFullScreen"" value=""true""></param> <embed src=""{6}{0}&fs=1&border={3}&color1={4}&color2={5}"" type = ""application/x-shockwave-flash"" width=""{1}"" height=""{2}"" allowfullscreen=""true""></embed> </object> </div>"; // Replace All The Value player = String.Format(player, mediaFile, youtubePlayerOption.Width, youtubePlayerOption.Height, (youtubePlayerOption.Border ? "1" : "0"), ConvertColorToHexa.ConvertColorToHexaString(youtubePlayerOption.PrimaryColor), ConvertColorToHexa.ConvertColorToHexaString(youtubePlayerOption.SecondaryColor), baseURL, playerId); //Retrun Embedded Code return new MvcHtmlString(player); } } public class YouTubePlayerOption { int _width = 425; int _height = 355; Color _color1 = Color.Black; Color _color2 = Color.Aqua; public YouTubePlayerOption() { Border = false; } public int Width { get { return _width; } set { _width = value; } } public int Height { get { return _height; } set { _height = value; } } public Color PrimaryColor { get { return _color1; } set { _color1 = value; } } public Color SecondaryColor { get { return _color2; } set { _color2 = value; } } public bool Border { get; set; } } public class ConvertColorToHexa { private static readonly char[] HexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; public static string ConvertColorToHexaString(Color color) { var bytes = new byte[3]; bytes[0] = color.R; bytes[1] = color.G; bytes[2] = color.B; var chars = new char[bytes.Length * 2]; for (int i = 0; i < bytes.Length; i++) { int b = bytes[i]; chars[i * 2] = HexDigits[b >> 4]; chars[i * 2 + 1] = HexDigits[b & 0xF]; } return new string(chars); } } }
نحوه استفاده:
@Html.YouTubePlayer("Casablanca", "iLdqKUkkM6w", new YouTubePlayerOption() { Border = true })
در اینجا جهت مقداردهی پارمترهای پخش کننده ویدئو، از کلاس YouTubePlayerOption استفاده شده است.
نظرات مطالب
EF Code First #2
- به هر قسمتی که فکر میکنید این مورد همزمانی ورود یا ویرایش اطلاعات امکان رخ دادن دارد، بله. بهتر است اضافه شود.
- تا زمانیکه خطایی نگرفتید، هیچ تنظیمی را تغییر ندهید.
برای یافتن schema، با استفاده از management studio به سرور متصل شده و یک جدول ساده را درست کنید. بعد مشاهده کنید که ابتدای نام جدول، به چه صورتی شروع شده. مثلا user1.table1 است؟ یا مورد دیگری.
- تا زمانیکه خطایی نگرفتید، هیچ تنظیمی را تغییر ندهید.
برای یافتن schema، با استفاده از management studio به سرور متصل شده و یک جدول ساده را درست کنید. بعد مشاهده کنید که ابتدای نام جدول، به چه صورتی شروع شده. مثلا user1.table1 است؟ یا مورد دیگری.