فصل | عنوان | فایل مرتبط |
21 | بررسی کنترل DataForm | + |
22 | برنامه نویسی گرافیکی در Silverlight | + |
23 | آشنایی با پویا نمایی در Silverlight | + |
24 | برنامه نویسی چند ریسمانی در Silverlight | + |
25 | تعامل با کدهای HTML صفحه در Silverlight | + |
26 | استفاده از WCF RIA Services در Silverlight | + |
27 | استفاده از MEF در Silverlight 4 | + |
| منابع و مآخذ | + |
| سورس تمام مثالهای کتاب | + |
توضیحی در مورد مثالها:
تمام پوشههای مثالها دارای شماره هستند و این شمارهها متناظرند با شمارهی فضاهای نام مثالها
Install-Package iTextSharp
شروع کار با iTextSharp
معمولا برای کار با iText یک سری روال تکراری از قبیل انتخاب نام فایل نهایی، تعریف فونت، سایز کاغذ، حاشیه بندی و ... را باید طی کنید که کدهای آن را در ذیل مشاهده میکنید:
var fileStream = new FileStream("card.pdf", FileMode.Create, FileAccess.Write, FileShare.None); var docFont = GetFont(); var pageSize = PageSize.A6.Rotate(); // سایز کارت را اینجا باید مشخص کرد var doc = new Document(pageSize); doc.SetMargins(18f, 18f, 15f, 2f); var pdfWriter = PdfWriter.GetInstance(doc, fileStream); doc.Open();
برای درج عکس به صورت شفاف در پس زمینه کارت باید از کد زیر استفاده کرد:
// درج لوگوی مسابقات به صورت شفاف در پس زمینه var canvas = pdfWriter.DirectContentUnder; var logoImg = Image.GetInstance(competitionImagePath); logoImg.SetAbsolutePosition(0, 0); logoImg.ScaleAbsolute(pageSize); var graphicsState = new PdfGState { FillOpacity = 0.2F }; canvas.SetGState(graphicsState); canvas.AddImage(logoImg);
چیدمان و طرح بندی بندی عناصر در iTextSharp
برای طراحی کارت یا کلا کار طراحی، باید با نحوهی قرار دادن و طرح بندی عناصر مثل تصاویر و نوشتهها و ابزارهای مورد نیاز برای این کار، آشنا شوید. خوشبختانه در iText برای این کار ابزارهای خوبی وجود دارد.
حتما با تگ Table در HTML آشنایی دارید. در سالهای دور، حتی کل صفحهی وب را به وسیلهی Table ساختار دهی میکردند. در iTextSharp نیز کلاسی به نام PdfPTable در دسترس است که میتوان از آن به عنوان قالبی برای قرار دادن عناصر، در صفحه استفاده کرد. این Table همانند هر جدولی دارای یک سری سطر و ستون است که میتوانیم عناصر مورد نظرمان مثل تصویر و نوشته و... را در آن قرار دهیم.
// جدولی که برای چیدمان عناصر ارم دانشگاه و عنوان و عکس شخص استفاده میشود var topTable = new PdfPTable(3) { WidthPercentage = 100, RunDirection = PdfWriter.RUN_DIRECTION_RTL, ExtendLastRow = false, }; var universityLogoImage = Image.GetInstance(universityLogoPath); universityLogoImage.ScaleAbsolute(70, 100); topTable.AddCell(new PdfPCell(universityLogoImage) { HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); topTable.AddCell(new PdfPCell(new Phrase("کارت مسابقات دانشگاه آزاد اسلامی", docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_CENTER, Border = 0, }); var userImage = Image.GetInstance(userModel.ImagePath); userImage.Border = Rectangle.TOP_BORDER | Rectangle.RIGHT_BORDER | Rectangle.BOTTOM_BORDER | Rectangle.LEFT_BORDER; userImage.BorderWidth = 1f; userImage.BorderColor = new BaseColor(204, 204, 204); // gray color userImage.ScaleAbsolute(70, 100); topTable.AddCell(new PdfPCell(userImage) { HorizontalAlignment = 2, Border = 0 }); int[] topTableColumnsWidth = { 10, 25, 10 }; topTable.SetWidths(topTableColumnsWidth); doc.Add(topTable);
public class UserModel { public string FirstName { get; set; } public string LastName { get; set; } public string StudentNumber { get; set; } public string NationalCode { get; set; } public string UniversityName { get; set; } public string ImagePath { get; set; } }
using System; using System.IO; using iTextSharp.text; using iTextSharp.text.pdf; using Font = iTextSharp.text.Font; using Image = iTextSharp.text.Image; using Rectangle = iTextSharp.text.Rectangle; namespace ITextSharpCardSample { public class CardReport { public static void Generate(UserModel userModel, string competitionImagePath, string universityLogoPath) { var fileStream = new FileStream("card.pdf", FileMode.Create, FileAccess.Write, FileShare.None); var docFont = GetFont(); var pageSize = PageSize.A6.Rotate(); // سایز کارت را اینجا باید مشخص کرد var doc = new Document(pageSize); doc.SetMargins(18f, 18f, 15f, 2f); var pdfWriter = PdfWriter.GetInstance(doc, fileStream); doc.Open(); // درج لوگوی مسابقات به صورت شفاف در پس زمینه var canvas = pdfWriter.DirectContentUnder; var logoImg = Image.GetInstance(competitionImagePath); logoImg.SetAbsolutePosition(0, 0); logoImg.ScaleAbsolute(pageSize); var graphicsState = new PdfGState { FillOpacity = 0.2F }; canvas.SetGState(graphicsState); canvas.AddImage(logoImg); // جدولی که برای چیدمان عناصر ارم دانشگاه و عنوان و عکس شخص استفاده میشود var topTable = new PdfPTable(3) { WidthPercentage = 100, RunDirection = PdfWriter.RUN_DIRECTION_RTL, ExtendLastRow = false, }; var universityLogoImage = Image.GetInstance(universityLogoPath); universityLogoImage.ScaleAbsolute(70, 100); topTable.AddCell(new PdfPCell(universityLogoImage) { HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); topTable.AddCell(new PdfPCell(new Phrase("کارت مسابقات دانشگاه آزاد اسلامی", docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_CENTER, Border = 0, }); var userImage = Image.GetInstance(userModel.ImagePath); userImage.Border = Rectangle.TOP_BORDER | Rectangle.RIGHT_BORDER | Rectangle.BOTTOM_BORDER | Rectangle.LEFT_BORDER; userImage.BorderWidth = 1f; userImage.BorderColor = new BaseColor(204, 204, 204); // gray color userImage.ScaleAbsolute(70, 100); topTable.AddCell(new PdfPCell(userImage) { HorizontalAlignment = 2, Border = 0 }); int[] topTableColumnsWidth = { 10, 25, 10 }; topTable.SetWidths(topTableColumnsWidth); doc.Add(topTable); // جدول مشخصات شرکت کننده مثل نام و نام خانوادگی var infoTable = new PdfPTable(4) { WidthPercentage = 100, RunDirection = PdfWriter.RUN_DIRECTION_RTL, ExtendLastRow = false, SpacingBefore = 15, }; infoTable.AddCell(new PdfPCell(new Phrase("نام:", docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0, PaddingBottom = 15 }); infoTable.AddCell(new PdfPCell(new Phrase(userModel.FirstName, docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); infoTable.AddCell(new PdfPCell(new Phrase("نام خانوادگی:", docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); infoTable.AddCell(new PdfPCell(new Phrase(userModel.LastName, docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); infoTable.AddCell(new PdfPCell(new Phrase("شماره\nدانشجویی:", docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0, PaddingBottom = 15 }); infoTable.AddCell(new PdfPCell(new Phrase(userModel.StudentNumber, docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); infoTable.AddCell(new PdfPCell(new Phrase("کد ملی:", docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); infoTable.AddCell(new PdfPCell(new Phrase(userModel.NationalCode, docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); infoTable.AddCell(new PdfPCell(new Phrase("واحد دانشگاهی:", docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); infoTable.AddCell(new PdfPCell(new Phrase(userModel.UniversityName, docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); // دو سلول بعدی صرفا جهت تکمیل شدن یک ردیف است تا عملکرد صحیح خود را داشته باشد infoTable.AddCell(new PdfPCell(new Phrase("", docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); infoTable.AddCell(new PdfPCell(new Phrase("", docFont)) { RunDirection = PdfWriter.RUN_DIRECTION_RTL, HorizontalAlignment = Element.ALIGN_LEFT, Border = 0 }); int[] infoTableColumnsWidth = { 20, 15, 20, 15 }; infoTable.SetWidths(infoTableColumnsWidth); doc.Add(infoTable); doc.Close(); } private static Font GetFont() { const string fontName = "Iranian Sans"; if (FontFactory.IsRegistered(fontName)) return FontFactory.GetFont(fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); var fontPath = "Fonts/irsans.ttf"; // مسیر فونت FontFactory.Register(fontPath); return FontFactory.GetFont(fontName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); } } }
class Program { static void Main(string[] args) { var userModel = new UserModel { FirstName = "علی", LastName = "احمدی", NationalCode = "1234567890", StudentNumber = "23242342", UniversityName = "آزاد", ImagePath = "Images/avatar.jpg" }; CardReport.Generate(userModel, "Images/competition_logo.jpg", "Images/university_logo.png"); System.Diagnostics.Process.Start("card.pdf"); } }
شروع به کار با ngrok
- قبل از ادامهی این آموزش، وارد سایت https://ngrok.com شده و بعد از ثبت نام، مطابق سیستم عاملی که دارید، فایل مخصوص آن را دریافت کنید.
- بعد از دریافت، فایل زیپ را از حالت فشرده خارج کنید. به محل فایل استخراج شده رفته و در یک مکان خالی در پوشهی جاری، دکمهی Shift را فشرده و سپس کلیک راست کنید و در آخر گزینهی Open Command Window Here را انتخاب نمائید و یا کلا از طریق cmd وارد پوشهی مربوطه شوید.
- سپس پروژهی خود را توسط ویژوال استودیو (IIS Express) و یا بر روی IIS لوکال خود، اجرا کنید.
- همانطور که در تصویر مشاهده میکنید؛ آدرس پروژهی لوکال ما به شکل زیر میباشد:
http://localhost:51095/Home/Index
- حال به cmd برمیگردیم و سپس با دستور زیر میتوانیم لوکالهاست خود را بر روی https به اشتراک بگذاریم:
ngrok http [port] -host-header="localhost:[port]"
همانطور که ملاحظه میفرمائید، هم http و هم https را در اختیار ما قرار میدهد. برای مثال اگر نیاز است با webhookهای تلگرام کار کنید، باید از آدرس https آن استفاده کنید.
در اینجا در قسمت HTTP Requests میتوانید درخواستهایی را که فرستاده میشوند، ببینید و یا میتوانید با رفتن به آدرس زیر، دستورات بالا را در نمایی گرافیکی و بصورت کامل نظارهگر باشید:
http://127.0.0.1:4040
برای نمونه، خروجی آن در گوشی و مرورگر آن، به شکل زیر است:
چند متد الحاقی پیشنهادی
بله صحبت شما کاملا صحیح است. من خودم اصلا از این متد استفاده نکرده بودم (صرفا فقط توی پروژه تعریف شده بود). من به قول معروف از حول حلیم افتادم تو دیگ چون از حول همکاری با اعضای DotNetTips سریع چندتا از متدهای الحاقی رو از روی پروژه Copy & Paste کردم.
باید دقت بیشتری میکردم اشتباه از من بوده. اگر امکانش هست توسط آقای اسم رام حذف شود.
با سپاس
ASP.NET MVC #13
در EF Code first هم به همین ترتیب. شما حق انتخاب دارید. به شخصه از ترکیب هر دو حالت Data Annotationها و Fluent API استفاده میکنم.
ViewModel فقط بحث مدیریت صحیح ارتباط با کلاینت است (نمایش اطلاعات View) و برعکس (دریافت اطلاعات از کاربر). بنابراین اگر از ViewModel استفاده میکنید، نیاز است از Data Annotationها استفاده کنید تا اعتبار سنجی سمت کاربر (که به صورت خودکار توسط MVC اعمال و مدیریت میشود) کار کند.
- ترلو ابزاری انعطاف پذیر است که شفافیت را در مدیریت هر گونه پروژه ای ( نه لزوما نرم افزاری ) برای شما به ارمغان میاره
- یکی از کاربرد هاش هم استفاده از اون بعنوان ابزاری برای مدیریت Taskها در اسکرام هست
- ترلو ابزاری منعطف و در عین حال بسیار ساده برای مدیریت پروژه است
- با ترلو شما میتونید آمار همه چیزو داشته باشید
EF Code First #15
EF Code first و بانکهای اطلاعاتی متفاوت
در آخرین قسمت از سری EF Code first بد نیست نحوه استفاده از بانکهای اطلاعاتی دیگری را بجز SQL Server نیز بررسی کنیم. در اینجا کلاسهای مدل و کدهای مورد استفاده نیز همانند قسمت 14 است و تنها به ذکر تفاوتها و نکات مرتبط اکتفاء خواهد شد.
حالت کلی پشتیبانی از بانکهای اطلاعاتی مختلف توسط EF Code first
EF Code first با کلیه پروایدرهای تهیه شده برای ADO.NET 3.5 که پشتیبانی از EF را لحاظ کرده باشند، به خوبی کار میکند. پروایدرهای مخصوص ADO.NET 4.0، تنها سه گزینه DeleteDatabase/CreateDatabase/DatabaseExists را نسبت به نگارش قبلی بیشتر دارند و EF Code first ویژگیهای بیشتری را طلب نمیکند.
بنابراین اگر حین استفاده از پروایدر ADO.NET مخصوص بانک اطلاعاتی خاصی با پیغام «CreateDatabase is not supported by the provider» مواجه شدید، به این معنا است که این پروایدر برای دات نت 4 به روز نشده است. اما به این معنا نیست که با EF Code first کار نمیکند. فقط باید یک دیتابیس خالی از پیش تهیه شده را به برنامه معرفی کنید تا مباحث Database Migrations به خوبی کار کنند؛ یا اینکه کلا میتوانید Database Migrations را خاموش کرده (متد Database.SetInitializer را با پارامتر نال فراخوانی کنید) و فیلدها و جداول را دستی ایجاد کنید.
استفاده از EF Code first با SQLite
برای استفاده از SQLite در دات نت ابتدا نیاز به پروایدر ADO.NET آن است: «مکان دریافت درایورهای جدید SQLite مخصوص دات نت»
ضمن اینکه به نکته «استفاده از اسمبلیهای دات نت 2 در یک پروژه دات نت 4» نیز باید دقت داشت.
و یکی از بهترین management studio هایی که برای آن تهیه شده: «SQLite Manager»
پس از دریافت پروایدر آن، ارجاعی را به اسمبلی System.Data.SQLite.dll به برنامه اضافه کنید.
سپس فایل کانفیگ برنامه را به نحو زیر تغییر دهید:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
<connectionStrings>
<clear/>
<add name="Sample09Context"
connectionString="Data Source=CodeFirst.db"
providerName="System.Data.SQLite"/>
</connectionStrings>
</configuration>
همانطور که ملاحظه میکنید، تفاوت آن با قبل، تغییر connectionString و providerName است.
اکنون اگر همان برنامه قسمت قبل را اجرا کنیم به خطای زیر برخواهیم خورد:
«The given key was not present in the dictionary»
در این مورد هم توضیح داده شد. سه گزینه DeleteDatabase/CreateDatabase/DatabaseExists در پروایدر جاری SQLite برای دات نت وجود ندارد. به همین جهت نیاز است فایل «CodeFirst.db» ذکر شده در کانکشن استرینگ را ابتدا دستی درست کرد.
برای مثال از افزونه SQLite Manager استفاده کنید. ابتدا یک بانک اطلاعاتی خالی را درست کرده و سپس دستورات زیر را بر روی بانک اطلاعاتی اجرا کنید تا دو جدول خالی را ایجاد کند (در برگه Execute sql افزونه SQLite Manager):
CREATE TABLE [Payees](
[Id] [integer] PRIMARY KEY AUTOINCREMENT NOT NULL,
[Name] [text] NULL,
[CreatedOn] [datetime] NOT NULL,
[CreatedBy] [text] NULL,
[ModifiedOn] [datetime] NOT NULL,
[ModifiedBy] [text] NULL
);
CREATE TABLE [Bills](
[Id] [integer] PRIMARY KEY AUTOINCREMENT NOT NULL,
[Amount] [float](18, 2) NOT NULL,
[Description] [text] NULL,
[CreatedOn] [datetime] NOT NULL,
[CreatedBy] [text] NULL,
[ModifiedOn] [datetime] NOT NULL,
[ModifiedBy] [text] NULL,
[Payee_Id] [integer] NULL
);
سپس سطر زیر را نیز به ابتدای برنامه اضافه کنید:
Database.SetInitializer<Sample09Context>(null);
به این ترتیب database migrations خاموش میشود و اکنون برنامه بدون مشکل کار خواهد کرد.
فقط باید به یک سری نکات مانند نوع دادهها در بانکهای اطلاعاتی مختلف دقت داشت. برای مثال integer در اینجا از نوع Int64 است؛ بنابراین در برنامه نیز باید به همین ترتیب تعریف شود تا نگاشتها به درستی انجام شوند.
در کل تنها مشکل پروایدر فعلی SQLite عدم پشتیبانی از مباحث database migrations است. این مورد را خاموش کرده و تغییرات ساختار بانک اطلاعاتی را به صورت دستی به بانک اطلاعاتی اعمال کنید. بدون مشکل کار خواهد کرد.
البته اگر به دنبال پروایدری تجاری با پشتیبانی از آخرین نگارش EF Code first هستید، گزینه زیر نیز مهیا است:
http://devart.com/dotconnect/sqlite/
برای مثال اگر علاقمند به استفاده از حالت تشکیل بانک اطلاعاتی SQLite در حافظه هستید (با رشته اتصالی ویژه Data Source=:memory:;Version=3;New=True;)، فعلا تنها گزینه مهیا استفاده از پروایدر تجاری فوق است؛ زیرا مبحث Database Migrations را به خوبی پشتیبانی میکند.
استفاده از EF Code first با SQL Server CE
قبلا در مورد «استفاده از SQL-CE به کمک NHibernate» مطلبی را در این سایت مطالعه کردهاید. سه مورد اول آن با EF Code first یکی است و تفاوتی نمیکند (یک سری بحث عمومی مشترک است). البته با یک تفاوت؛ در اینجا EF Code first قادر است یک بانک اطلاعاتی خالی SQL Server CE را به صورت خودکار ایجاد کند و نیازی نیست تا آنرا دستی ایجاد کرد. مباحث database migrations و به روز رسانی خودکار ساختار بانک اطلاعاتی نیز در اینجا پشتیبانی میشود.
برای استفاده از آن ابتدا ارجاعی را به اسمبلی System.Data.SqlServerCe.dll قرار گرفته در مسیر Program Files\Microsoft SQL Server Compact Edition\v4.0\Desktop اضافه کنید.
سپس رشته اتصالی به بانک اطلاعاتی و providerName را به نحو زیر تغییر دهید:
<connectionStrings>
<clear/>
<add name="Sample09Context"
connectionString="Data Source=mydb.sdf;Password=1234;Encrypt Database=True"
providerName="System.Data.SqlServerCE.4.0"/>
</connectionStrings>
بدون نیاز به هیچگونه تغییری در کدهای برنامه، همین مقدار تغییر در تنظیمات ابتدایی برنامه برای کار با SQL Server CE کافی است.
ضمنا مشکلی هم با فیلد Identity در آخرین نگارش EF Code first وجود ندارد؛ برخلاف حالت database first آن که پیشتر این اجازه را نمیداد و خطای «Server-generated keys and server-generated values are not supported by SQL Server Compact» را ظاهر میکرد.
استفاده از EF Code first با MySQL
برای استفاده از EF Code first با MySQL (نگارش 5 به بعد البته) ابتدا نیاز است پروایدر مخصوص ADO.NET آنرا دریافت کرد: (^)
که از EF نیز پشتیبانی میکند. پس از نصب آن، ارجاعی را به اسمبلی MySql.Data.dll قرار گرفته در مسیر Program Files\MySQL\MySQL Connector Net 6.5.4\Assemblies\v4.0 به پروژه اضافه نمائید.
سپس رشته اتصالی و providerName را به نحو زیر تغییر دهید:
<connectionStrings>
<clear/>
<add name="Sample09Context"
connectionString="Datasource=localhost; Database=testdb2; Uid=root; Pwd=123;"
providerName="MySql.Data.MySqlClient"/>
</connectionStrings>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient"/>
<add name="MySQL Data Provider"
invariant="MySql.Data.MySqlClient"
description=".Net Framework Data Provider for MySQL"
type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
همانطور که مشاهده میکنید در اینجا شماره نگارش دقیق پروایدر مورد استفاده نیز ذکر شده است. برای مثال اگر چندین پروایدر روی سیستم نصب است، با مقدار دهی DbProviderFactories میتوان از نگارش مخصوصی استفاده کرد.
با این تغییرات پس از اجرای برنامه قسمت قبل، به خطای زیر برخواهیم خورد:
The given key was not present in the dictionary
توضیحات این مورد با قسمت SQLite یکی است؛ به عبارتی نیاز است بانک اطلاعاتی testdb را دستی درست کرد. همچنین جداول و فیلدها را نیز باید دستی ایجاد کرد و database migrations را نیز باید خاموش کرد (پارامتر Database.SetInitializer را به نال مقدار دهی کنید).
برای این منظور یک دیتابیس خالی را ایجاد کرده و سپس دو جدول زیر را به آن اضافه کنید:
CREATE TABLE IF NOT EXISTS `bills` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Amount` float DEFAULT NULL,
`Description` varchar(400) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`CreatedOn` datetime NOT NULL,
`CreatedBy` varchar(400) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`ModifiedOn` datetime NOT NULL,
`ModifiedBy` varchar(400) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`Payee_Id` int(11) NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `payees` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(400) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`CreatedOn` datetime NOT NULL,
`CreatedBy` varchar(400) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
`ModifiedOn` datetime NOT NULL,
`ModifiedBy` varchar(400) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=1 ;
پس از این تغییرات، برنامه بدون مشکل اجرا خواهد شد (ایجاد بانک اطلاعاتی خالی به همراه ایجاد ساختار جداول و خاموش کردن database migrations که توسط این پروایدر پشتیبانی نمیشود).
به علاوه پروایدر تجاری دیگری هم در سایت devart.com برای MySQL و EF Code first مهیا است که مباحث database migrations را به خوبی مدیریت میکند.
مشکل!
اگر به همین نحو برنامه را اجرا کنیم، فیلدهای یونیکد فارسی ثبت شده در MySQL با «??????? ?? ????» مقدار دهی خواهند شد و تنظیم CHARACTER SET utf8 COLLATE utf8_persian_ci نیز کافی نبوده است (این مورد با SQLite یا نگارشهای مختلف SQL Server بدون مشکل کار میکند و نیاز به تنظیم اضافهتری ندارد):
ALTER TABLE `bills` DEFAULT CHARACTER SET utf8 COLLATE utf8_persian_ci
برای رفع این مشکل توصیه شده است که CharSet=UTF8 را به رشته اتصالی به بانک اطلاعاتی اضافه کنیم. اما در این حالت خطای زیر ظاهر میشود:
The provider did not return a ProviderManifestToken string
این مورد فقط به اشتباه بودن تعاریف رشته اتصالی بر میگردد؛ یا عدم پشتیبانی از تنظیم اضافهای که در رشته اتصالی ذکر شده است.
مقدار صحیح آن دقیقا مساوی CHARSET=utf8 است (با همین نگارش و رعایت کوچکی و بزرگی حروف؛ مهم!):
<connectionStrings>
<clear/>
<add name="Sample09Context"
connectionString="Datasource=localhost; Database=testdb; Uid=root; Pwd=123;CHARSET=utf8"
providerName="MySql.Data.MySqlClient"/>
</connectionStrings>
به این ترتیب، مشکل ثبت عبارات یونیکد فارسی برطرف میشود (البته جدول هم بهتر است به DEFAULT CHARACTER SET utf8 COLLATE utf8_persian_ci تغییر پیدا کند؛ مطابق دستور Alter ایی که در بالا ذکر شد).
سایت CodePlex و SVN
اگر سورس پروژه Google book downloader را بخواهید از طریق سایت CodePlex دریافت کنید چند صد مگابایت خواهد شد. علت هم این است که نویسنده پروژه تمام نگارشهای قبلی را نیز در این مکان نگهداری میکند و وب سایت CodePlex هم اجازهی انتخاب فقط trunk را جهت دریافت نمیدهد. یا همه را باید دریافت کنید یا هیچ.
راه میانبری برای دریافت سادهتر این پروژه نیز وجود دارد. مدتها است که امکان اتصال به این سایت از طریق کلاینتهای SVN مانند TortoiseSVN نیز فراهم شده است. فقط کافی است برای دریافت سورس کامل یک پروژه در CodePlex ، مسیر زیر را Checkout کرد:
برای مثال جهت دریافت فقط trunk این پروژه، میتوان مسیر زیر را checkout کرد:
Claim Based Identity
Relying Party (RP) = Application
Service Providers (SP) = Application
RP یا SP یک Application میباشد که از Claim استفاده میکند. واژهی Relying Party بدین دلیل انتخاب شده که Application روی یک Issuer به منظور تامین اطلاعات در مورد یک Identity تکیه میکند.
Subject = User
Principal = User
واژهی Subject یا Principal در حقیقت یک User میباشد. این واژه زمانی معنا پیدا میکند که شما به User به عنوان یک Subject برای کنترل دسترسی، شخصی سازی (Personalization) و ... بنگرید. در Net Framework. به جای Subject از Principal استفاده میشود.
Security Token Service (STC) = Issuer
از دید فنی، STC یک رابط درون یک Issuer میباشد که درخواستها (Request) را تأیید و اقدام به ساخت Issues Security Token (توکنهای مسائل امنیتی) مینماید. توکنهای مسائل امنیتی شامل یک سری Claim میباشند.
Identity Provider (IDP) = Issuer
تامین کننده Identity یک Issuer یا Token Issuer میباشد که وظیفهی تعیین اعتبار (Validation) کاربر مانند نام کاربری، رمز عبور و ... را بر عهده دارد.
Active Client = Smart or rich Client
Passive Client = Browser
یک Active Client میتواند از یک کتابخانهی پیچیده مانند WCF به منظور پیاده سازی پروتکلهایی که بتوانند یک Security Token را درخواست و پاس دهند، استفاده نمایند. به منظور پشتیبانی از مرورگرهای مختلف، سناریوهای passive از پروتکلهای سادهتری به منظور درخواست و پاس دادن یک Security Token که بر روی پروتکل Http تکیه دارد استفاده میکند (Http Post - Http Get).
و اما Claim چیست؟
در حقیقت Claim عبارتست از یک بیانیه یا شرح که یک Subject در مورد خودش یا Subject دیگری میسازد. این بیانیه میتواند در مورد یک نام، هویت، کلید، گروه، حق دسترسی و یا یک قابلیت باشد. Claimها بوسیله یک Provider صادر و سپس بسته بندی (Package) شده و بوسیلهی یک Issuer صادر میشوند که این Issuer عموما با نام Security Token Service شناخته میشود.
به منظور آشنایی با این مبحث میتوانید به اینجا و اینجا مراجعه نمایید.
این نوشتار مقدمهای بود بر مباحث ASP.NET Identity. بنده در حال ترجمهی سه فصل آخر کتاب Pro ASP.NET Mvc 5 Platform که اختصاص به مبحث Identity دارد هستم. فصل 13 تقریبا تمام شده و انشالله بزودی آنرا منتشر میکنم.