خلاصه اشتراکهای روز جمعه 4 آذر 1390
ضمنا HTML5 تا سال 2022 کار داره برای پخته شدن. همچنین تهیه ابزارهای مناسب برای توسعه آن، آموزش و غیره. به علاوه مرورگرهایی با پشتیبانی کامل از آن به همراه وفق یافتن سازمانها که همیشه یک تا دو سال به عمد از جریانات روز عقب هستند و همیشه سیستمهای پایدار رو نصب میکنند تا اینکه مثلا هیجان زده هر روز فایرفاکس را به روز کنند. این یک واقعیت سازمانی است.
در کل هدف اصلی Silverlight هیچ وقت توسعه وب سایت نبوده. هدفش توسعه «برنامه»های غنی وب بوده. مثلا عمده کاربرد آن برای مایکروسافت تابحال درست کردن کنترل پنلهای مدیریتی یک سری از برنامههای سرور اصلی خودش بوده مثلا lync server مثلا windows intune و غیره. یکبار مثالش رو در سایت زدم. بگردید هست.
- 16 نکته در طراحی وب | (مجتبی بنائی) | www.banaie.ir
- SQL Server 2012 نام رسمی محصول بعدی مایکروسافت! | www.persiadevelopers.com
- ابزارهای استخراج اطلاعات از صفحات وب | (Afshar Mohebbi) | blog.afsharm.com
- اوراکل پروژه OpenOffice.org را به آپاچی هبه کرد | (مرضیه نورعلیان) | www.knowtechmag.com
- ضرورت تکنولوژی | (Afshar Mohebbi) | blog.afsharm.com
- DirectX 11 DirectCompute | www.microsoft.com
- استفاده از اکانت جی میل جهت برپایی bug tracking server | codebetter.com
- امکان اعمال فیلتر بر روی SVG در IE-10 | blogs.msdn.com
- آیا کارت گرافیکی من از DirectX 11 پشتیبانی میکند؟ | www.danielmoth.com
- کمی در مورد SOA و مطلبی که از گوگل به بیرون درز کرده | blogs.msdn.com
- معرفی پروژه irony | www.hanselman.com
- نصب آسان با استفاده از Nuget
- بدون نیاز به هیچگونه وب سرویس و یا دانش پیاده سازی سیستمهای پرداخت آنلاین
- پشتیبانی از درگاههای: ملت، ملی (سداد)، پارسیان، پاسارگاد، ایران کیش، سامان و آسان پرداخت ، زرین پال، پی آی آر و آی دی پی
- انجام پرداخت، فقط با نوشتن ۳ خط کد
- طراحی کاملا یکپارچه برای انجام عملیات پرداخت با تمامی بانکها
- رعایت نکات امنیتی پرداخت آنلاین
- درگاه مجازی، برای شبیه سازی عملیات پرداخت
- امکان استفاده از پروکسی برای سرورهای خارج از ایران در صورت نیاز
- استفاده از تکنولوژیهای مدرن و استاندارد
- قابل نصب بر روی پروژههای: ASP.NET Core, ASP.NET MVC, ASP.NET WebForms
امن سازی برنامههای وب همواره چالش برانگیز بودهاست؛ خصوصا این روزها که نیاز است برنامهها، خارج از دیوارهای یک شرکت نیز در دسترس باشند و توسط انواع و اقسام وسایل ارتباطی مورد استفاده قرار گیرند. در سالهای قبل، عموما برنامههای thick clients مانند WPF و WinForms برای شرکتها توسعه داده میشدند و یا برنامههای وب مانند ASP.NET Web Forms که مبتنی بر سرویسها نبودند. در برنامههای ویندوزی، پس از لاگین شخص به شبکه و دومین داخلی شرکت، عموما از روش Windows Authentication برای مشخص سازی سطوح دسترسی کاربران استفاده میشود. در برنامههای Web Forms نیز بیشتر روش Forms Authentication برای اعتبارسنجی کاربران مرسوم است. امن سازی این نوع برنامهها سادهاست. عموما بر روی یک دومین ارائه میشوند و کوکیهای اعتبارسنجی کاربران برای ارائهی مباحثی مانند single sign-on (داشتن تنها یک صفحهی لاگین برای دسترسی به تمام برنامههای شرکت)، میسر است.
عصر شروع بهکارگیری سرویسهای وب
در سالهای اخیر این شیوهی کاری تغییر کرده و بیشتر بر اساس بکارگیری برنامههای مبتنی بر سرویسها شدهاست. برای مثال برای این مورد استاندارد WS-Security مربوط به WCF ارائه شدهاست که باز هم مرتبط است به برنامههای یک دومین و یا یک Application pool. اگر تعداد دومینها بیشتر شوند و نیاز به ارتباط امن بین آنها باشد، استاندارد SAML 2.0 مورد استفاده قرار میگرفت که هدف از آن، انتقال امن اعتبارسنجی و سطوح دسترسی کاربران بین دومینهای مختلف است. همانطور که ملاحظه میکنید تمام این برنامهها و استانداردها، داخل دیوارهای یک شرکت و یک دومین زندگی میکنند.
عصر شروع بهکارگیری Restful-API's
پس از آن باز هم شیوهی طراحی برنامههای تغییر کرد و شروع به ایجاد Restful-API's و HTTP API's کردیم. اینها دیگر الزاما داخل یک دومین ارائه نمیشوند و گاهی از اوقات حتی تحت کنترل ما هم نیستند. همچنین برنامههای ارائه شده نیز دیگر thick clients نیستند و ممکن است برنامههای سمت کلاینت Angular و یا حتی موبایل باشند که مستقیما با سرویسهای API برنامهها کار میکنند. حتی ممکن است یک API را طراحی کنیم که با یک API دیگر کار میکند.
در این حالت دیگر نمیتوان این APIها را با نگهداری آنها داخل دیوارهای یک شرکت محافظت کرد. اگر قرار است با یک HTTP API کار کنیم، این API باید عمومی باشد و در اینجا دیگر نمیتوان از روش Forms Authentication استفاده کرد. زیرا این روش اعتبارسنجی مختص برنامههای سمت سرور قرار گرفتهی در یک دومین طراحی شدهاست و آنچنان سازگاری با برنامههای سمت کلاینت و موبایل خارج از دیوارهای آن ندارد. همچنین ارسال نام کاربری و کلمهی عبور به ازای هر درخواست نیز روشی بسیار بدوی و نا امن است. اینجا است که عصر امن سازی برنامهها به کمک توکنها شروع میشود. با استفادهی از توکنها، بجای هر بار ارسال نام کاربری و کلمهی عبور به ازای هر درخواست از API، صرفا لیست سطوح دسترسی امضا شدهی به امکاناتی خاص، ارسال میشوند.
عصر شروع بهکارگیری Security Tokens
بنابراین در اینجا نیاز به برنامهای برای تولید توکنها و ارسال آنها به کلاینتها داریم. روش متداول پیاده سازی آن، ساخت یک برنامهی ابتدایی، برای دریافت نام کاربری و کلمهی عبور از کاربران و سپس بازگشت یک JSON Web Token به آنها است که بیانگر سطوح دسترسی آنها به قسمتهای مختلف برنامه است و کاربران باید این توکن را به ازای هر درخواستی به سمت سرور (بجای نام کاربری و کلمهی عبور و خود) ارسال کنند.
مشکل این روش در اینجا است که آن برنامهی خاص، باید از نام کاربری و کلمهی عبور کاربران مطلع باشد تا بتواند توکن مناسبی را برای آن کاربر خاص تولید کند. هر چند این روش برای یک تک برنامهی خاص بسیار مناسب به نظر میرسد، اما در یک شرکت، دهها برنامه مشغول به کارند و به اشتراک گذاری نام کاربری و کلمهی عبور کاربران، با تک تک آنها ایدهی مناسبی نیست و پس از مدتی از کنترل خارج خواهد شد. برای مثال کاربری در یک برنامه، کلمهی عبور خود را تغییر میدهد اما در برنامهای دیگر خیر و همین مسالهی عدم هماهنگی بین برنامهها و همچنین بخشهای مختلف یک شرکت، مدیریت یک دست برنامهها را تقریبا غیر ممکن میکند. همچنین در اینجا برنامههای ثالث را نیز باید در نظر داشت که آیا ضروری است آنها به ریز اطلاعات کاربران شرکت دسترسی پیدا کنند؟
به علاوه مشکل دیگر توسعهی این نوع برنامههای صدور توکن خانگی، اختراع مجدد چرخ است. در اینجا برای بهبود امنیت برنامه باید منقضی شدن، تمدید، امضای دیجیتال و اعتبارسنجی توکنها را خودمان پیاده سازی کنیم. توسعهی یک چنین سیستمی اگر غیرممکن نباشد، بسیار سخت و پیچیده است و همچنین باید باگهای امنیتی ممکن را نیز مدنظر داشت.
بنابراین تا اینجا به این نتیجه رسیدهایم که دیگر نمیخواهیم مدیریت نام کاربری و کلمهی عبور کاربران را در سطح هیچکدام از برنامههای خود انجام دهیم و هیچکدام از آنها قرار نیست دریافت کنندهی این اطلاعات باشند. قرار است این کار، به یک تک برنامهی مرکزی مخصوص اینکار منتقل شود و برای اینکار نیاز به پروتکلی امن است که بتوان این توکنهای تولیدی را ارسال و پردازش کرد.
حرکت به سمت «تامین کنندهی هویت مرکزی»
در گذشته، هر تک برنامهای دارای صفحهی لاگین و امکانات مدیریت کاربران آن، تغییر کلمهی عبور، تنظیم مجدد آن و اینگونه عملیات بود. اینروزها دیگر چنین کاری مرسوم نیست. این وظیفهی برنامهی شما نیست که بررسی کند کاربر وارد شدهی به سیستم کیست و آیا ادعای او صحیح است یا خیر؟ این نوع عملیات وظیفهی یک Identity provider و یا به اختصار IDP است. کار IDP اعتبارسنجی کاربر و در صورت نیاز، ارائهی اثبات هویت کاربر، به برنامهی درخواست کنندهاست.
در یک IDP عملیاتی مانند ثبت کاربران و مدیریت آنها انجام میشود. اینجا است که مفاهیمی مانند قفل کردن اکانت و یا تغییر کلمهی عبور و امثال آن انجام میشود و نه اینکه به ازای هر برنامهی تهیه شدهی برای یک شرکت، آن برنامه راسا اقدام به انجام چنین عملیاتی کند. به این ترتیب میتوان به امکان استفادهی مجدد از اطلاعات هویت کاربران و سطوح دسترسی آنها در بین تمام برنامههای موجود رسید.
همچنین با داشتن یک برنامهی IDP خوب پیاده سازی شده، از توزیع باگهای امنیتی مختلف در بین برنامههای گوناگون تهیه شده که هر کدام سیستم امنیتی خاص خودشان را دارند، جلوگیری خواهد شد. برای مثال فرض کنید میخواهید الگوریتم هش کردن پسوردهای سیستم را که امروز نا امن اعلام شدهاست، تغییر دهید. با داشتن یک IDP، دیگر نیازی نیست تا تمام برنامههای خود را برای رفع یک چنین باگهایی، تک تک تغییر دهید.
به علاوه این روزها روش استفادهی از نام کاربری و کلمهی عبور، تنها راه ورود به یک سیستم نیست و استفاده از کلیدهای دیجیتال و یا روشهای ویژهی ابزارهای موبایل نیز به این لیست اضافه شدهاند.
حرکت به سمت استاندارد OAuth 2
OAuth 2.0 پروتکلی است استاندارد، برای Authorization امن کاربران، توسط برنامههای وب، موبایل و دسکتاپ. به این ترتیب میتوان امکان دسترسی یک برنامه را به یک API، به نحوی استاندارد و امن میسر ساخت. OAuth 2.0 یک توکن دسترسی (Access token) را تولید میکند و در اختیار کلاینت قرار میدهد. سپس آن کلاینت با ارسال این توکن به API مدنظر، امکان دسترسی به امکانات مختلف آنرا خواهد یافت. به علاوه چون ماهیت برنامههای کلاینت وب و غیر وب متفاوت است، این استاندارد نحوهی دریافت چنین توکنی را برای برنامههای مختلف نیز تعریف میکند. به این ترتیب موارد مشترکی مانند تولید و نحوهی انتقال توکنها به کلاینتهای مختلف توسط این پروتکل استاندارد بیان میشود. در این حالت راهحلهای خانگی ما تبدیل به راهحلهایی میشوند که استاندارد OAuth 2.0 را پیاده سازی کرده باشند. بنابراین IDP ما باید بر مبنای این استاندارد تهیه شده باشد. برای مثال IdentityServer که در این سری بررسی خواهد شد و یا Azure Active Directory، نمونهای از IDPهایی هستند که این استاندارد را کاملا پیاده سازی کردهاند.
البته باید دقت داشت که این توکنهای دسترسی، تنها سطوح دسترسی به منابع API را مشخص میکنند و یا به عبارتی عملیات Authorization توسط آنها میسر میشود. عملیات ورود به سیستم اصطلاحا Authentication نام دارد و توسط استاندارد دیگری به نام OpenID Connect مدیریت میشود.
حرکت به سمت استاندارد OpenID Connect
OpenID Connect یک لایهی امنیتی بر فراز پروتکل OAuth 2.0 است که به اختصار به آن OIDC نیز گفته میشود. توسط آن یک کلاینت میتواند یک Identity token را علاوه بر Access token درخواست کند. از این Identity token برای ورود به برنامهی کلاینت استفاده میشود (Authentication) و پس از آن، برنامهی کلاینت بر اساس سطوح دسترسی تعریف شدهی در Access token، امکان دسترسی به امکانات مختلف یک API را خواهد یافت (Authorization). همچنین OpenID Connect امکان دسترسی به اطلاعات بیشتری از یک کاربر را نیز میسر میکند.
بنابراین OpenID Connect پروتکلی است که در عمل استفاده میشود و توسعه دهنده و جایگزین کنندهی پروتکل OAuth 2.0 میباشد. هرچند ممکن است در بسیاری از منابع صرفا به OAuth 2.0 بپردازند، اما در پشت صحنه با همان OpenID Connect کار میکنند.
مزیت دیگر کار با OpenID Connect، عدم الزام به استفادهی از API، در برنامهای خاص و یا قدیمی است. اگر برنامهی وب شما با هیچ نوع API ایی کار نمیکند، باز هم میتوانید از امکانات OpenID Connect بهرهمند شوید.
همانطور که میدانید هنگامیگه در ادیتور ارسال مطلب یکی از شبکههای اجتماعی (فیسبوک ، توییتر ، گوگل پلاس و ...) آدرس سایتی را وارد میکنید، بلافاصله لینک پردازش شده و پیش نمایشی از آن وبسایت در ادیتور نمایش داده میشود. برخی پیش نمایشها حاوی عکس، عنوان لینک و خیلی منظم هستند و برخی دیگر فقط نام و عنوان سایت را در برمیگیرند.
برای نمونه به تصاویر زیر دقت کنید:
تصویر فوق مربوط به لینک یک سایت خبری در ادیتور فیسبوک میباشد. همانطور که میبینید عنوان خبر، عکس و توضیح مختصری در مورد خبر، با نظم و ترتیبی خاص نمایش داده شده است.
حال به تصویر زیر که مربوط به لینکی از همین سایت میباشد دقت کنید:
همانطور که میبینید، تنها لینکی ساده، بدون هیچ پیش نمایشی از وب سایت نشان داده شده است.
دلیل این اتفاق وجود یا عدم وجود متاتگهایی که Social Media Metadata نامیده میشوند میباشند. چنانچه وب سایتی بوسیلهی این متاتگها برای شبکههای اجتماعی بهینه سازی شده باشد، با قرار دادن هر لینکی در ادیتور شبکههای اجتماعی، پیش نمایشی خوب از آن مطلب به نمایش گذاشته میشود. اهمیت این متاتگها در سایتهای خبری، فروشگاهها، سایتهای آموزشی و ... بسیار بالا میباشد تا از مزایای جذب کاربر توسط شبکههای اجتماعی بهرهمند شوند. با این مقدمه میرویم به سراغ معرفی و چگونگی بکارگیری این متاتگ ها.
بخش اول: متاتگهای موردنیاز برای لینکهای حاوی مقالات:
ابتدا تگ html خود را به شکل زیر تغییر دهید:
<html itemscope itemtype="http://schema.org/Article">
<title>عنوان صفحه ، حداکثر 60 تا 70 کارکتر باشد</title> <meta name="description" content="شرح صفحه ، حداکثر 150 کارکتر باشد" /> <!-- Schema.org markup for Google+ --> <meta itemprop="name" content="نام یا عنوان صفحه"> <meta itemprop="description" content="شرح صفحه"> <meta itemprop="image" content="نشانی اینترنتی عکسی که در پیشنمایش نشان داده میشود"> <!-- Twitter Card data --> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="کپی رایت نام سایت"> <meta name="twitter:title" content="نام یا عنوان صفحه"> <meta name="twitter:description" content="شرح صفحه"> <meta name="twitter:creator" content="نویسنده"> <!-- Picture size at least 280x150px -->عکس پیشنمایش با ابعاد حداقل <meta name="twitter:image:src" content="نشانی اینترنتی عکس مطلب"> <!-- Open Graph data --> <meta property="og:title" content="عنوان صفحه" /> <meta property="og:type" content="article" /> <meta property="og:url" content="نشانی سایت" /> <meta property="og:image" content="نشانی عکس مطلب" /> <meta property="og:description" content="شرح مطلب" /> <meta property="og:site_name" content="نام سایت" /> <meta property="article:published_time" content="تاریخ انتشار" /> <meta property="article:modified_time" content="تاریخ بروزرسانی" /> <meta property="article:section" content="نام بخش محتوی متن مقاله" /> <meta property="article:tag" content="نام تگ محتوی متن مقاله" /> <meta property="fb:admins" content="شناسه عددی کاربری شما در فیسبوک" />
بخش دوم: متاتگهای موردنیاز برای لینکهای حاوی محصولات:
ابتدا تگ html خود را به شکل زیر تغییر دهید:
<html itemscope itemtype="http://schema.org/Product">
<title>عنوان صفحه</title> <meta name="description" content="شرح صفحه" /> <!-- Schema.org markup for Google+ --> <meta itemprop="name" content="عنوان صفحه"> <meta itemprop="description" content="Tشرح صفحه"> <meta itemprop="image" content="نشانی عکس محصول یا کالا"> <!-- Twitter Card data --> <meta name="twitter:card" content="product"> <meta name="twitter:site" content="کپی رایت سایت"> <meta name="twitter:title" content="عنوان صفحه"> <meta name="twitter:description" content="شرح محصول یا کالا"> <meta name="twitter:creator" content="نویسنده"> <meta name="twitter:image" content="نشانی عکس محصول یا کالا"> <meta name="twitter:data1" content="قیمت محصول یا کالا"> <meta name="twitter:label1" content="Price"> <meta name="twitter:data2" content="رنگ کالا یا محصحول"> <meta name="twitter:label2" content="Color"> <!-- Open Graph data --> <meta property="og:title" content="عنوان صفحه" /> <meta property="og:type" content="article" /> <meta property="og:url" content="نشانی سایت" /> <meta property="og:image" content="عکس محصول یا کالا" /> <meta property="og:description" content="شرح مصحول" /> <meta property="og:site_name" content="نام سایت" /> <meta property="og:price:amount" content="قیمت محصول یا کالا" /> <meta property="og:price:currency" content="واحد ارزی قیمت" />
در پایان
برای مشاهده لیست کاملی از اسکیما اینجا را ببینید.
og مخفف Open Graph Protocol میباشد که میتوانید مطالب کاملی را در مورد آن اینجا بخوانید.
و برای آشنایی بیشتر با TwitterCard هم این لینک را مشاهده کنید.
چقدر خوب میشد اگر IDE ویژوال استودیو دات نت اشیایی از نوع disposable را برای ما مشخص میکرد و در ادامه پیشنهاد استفاده از عبارت using را برای آنها میداد؟
سؤال: این مساله چه اهمیتی دارد؟
به مثال متداول زیر دقت بفرمائید:
string connString = "...";
SqlConnection conn = new SqlConnection(connString);
string cmdString = "select * from author where name=N'test'";
SqlCommand cmd = new SqlCommand(cmdString, conn);
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
...
}
conn.Close();
Exception Details: System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
using (SqlConnection connection =
new SqlConnection(connectionString))
{
...
Agent Johnson در حقیقت پلاگینی است برای پلاگین دیگری به نام Resharper . این پلاگین را از آدرس زیر میتوان دریافت کرد (احتمالا به یک پروکسی نیاز خواهد بود ...):
http://code.google.com/p/agentjohnsonplugin/
البته بحث تشخیص اشیاء disposable یکی از تواناییهای آن است. سایر موارد را در آدرس فوق میتوانید مشاهده نمائید.
Memento یک الگوی طراحی مفید و ساده است که برای ذخیره و بازیابی state یک object استفاده میشود. در بعضی از مقالات از آن به عنوان snapshot نیز یاد شده است! اگر با git کار کرده باشید، این مفهوم را میتوان در git بسیار یافت؛ هر commit به عنوان یک snapshot میباشد که میتوان به صورت مکرر آن را undo کرد و یا مثال خیلی سادهتر میتوان به ctrl+z در سیستم عامل اشاره کرد.
به مثال زیر توجه کنید:
Int temp; Int a=1; temp=a; a=2; . . a=temp;
شما قطعا در برنامه نویسی با کد بالا زیاد برخورد داشتهاید و آنرا به صورت مکرر انجام دادهاید. کد بالا را در قالب یک object بیان میکنیم. به مثال زیر توجه کنید:
int main() { MyClass One = new MyClass(); MyClass Temp = new MyClass(); // Set an initial value. One.Value = 10; One.Name = "Ten"; // Save the state of the value. Temp.Value = One.Value; Temp.Name = One.Name; // Change the value. One.Value = 99; One.Name = "Ninety Nine"; // Undo and restore the state. One.Value = Temp.Value; One.Name = Temp.Name; }
در کد بالا با استفاده از یک temp، شیء مورد نظر را ذخیره کرده و در آخر مجدد دادهها را درون شیء، restore میکنیم.
از مشکلات کد بالا میتوان گفت :
۱- برای هر object باید یک شیء temp ایجاد کنیم.
۲- ممکن است بخواهیم که حالات یک object را بر روی هارد ذخیره کنیم. با روش فوق کدها خیلی پیچیدهتر خواهند شد.
۳- نوشتن کد به این سبک برای پروژههای بزرگ، پیچیده و مدیریت آن سختتر میشود.
پیاده سازی memento
ما این مثال را در قالب یک پروژه NET Core onsole. ایجاد میکنیم. برای این کار یک پوشهی جدید را ایجاد و درون ترمینال دستور زیر را وارد کنید:
dotnet new console
روشهای زیادی برای پیاده سازی memento وجود دارند. برای پیاده سازی memento ابتدا یک abstract class را به شکل زیر ایجاد میکنیم:
abstract class MementoBase { protected Guid mementoKey = Guid.NewGuid(); abstract public void SaveMemento(Memento memento); abstract public void RestoreMemento(Memento memento); }
اگر به کلاس بالا دقت کنید، این کلاس قرار است parent کلاسهای دیگری باشد که داری دو متد SaveMemento و RestoreMemento برای ذخیره و بازیابی و همچنین یک Guid برای نگهداری stateهای مختلف میباشد.
ورودی متدها از نوع memento میباشد. پس کلاس memento را به شکل زیر ایجاد میکنیم:
class Memento { private Dictionary<Guid, object> stateList = new Dictionary<Guid, object>(); public object GetState(Guid key) { return stateList[key]; } public void SetState(Guid key, object newState) { stateList[key] = newState; } public Memento() { } }
در کد بالا با یک Dictionary میتوان هر object را با کلیدش ذخیره کنیم. توجه کنید که value دیکشنری از نوع object میباشد و چون object پدر تمام objectهای دیگر است پس میتوانیم هر نوع دادهای را در آن ذخیره کنیم. تا اینجا، Memento پیاده سازی شده است. میتوان این کار را با جنریکها نیز پیاده سازی کرد.
در ادامه میخواهیم یک کلاس بسازیم و حالتهای مختلف را در آن بررسی کنیم. کلاس زیر را ایجاد کنید:
class ConcreteOriginator : MementoBase { private int value = 0; public ConcreteOriginator(int newValue) { SetData(newValue); } public void SetData(int newValue) { value = newValue; } public void Speak() { Console.WriteLine("My value is " + value.ToString()); } public override void SaveMemento(Memento memento) { memento.SetState(mementoKey, value); } public override void RestoreMemento(Memento memento) { int restoredValue = (int)memento.GetState(mementoKey); SetData(restoredValue); } }
کلاس ConcreteOriginator از کلاس MementoBase ارث بری کرده و دو متد RestoreMemento و SaveMemento را پیاده سازی میکند و همچنین دارای یک مشخصه value میباشد. برای خروجی گرفتن، متد main را به صورت زیر پیاده سازی میکنیم:
static void Main(string[] args) { Memento memento = new Memento(); // Create an originator, which will hold our state data. ConcreteOriginator myOriginator = new ConcreteOriginator("Hello World!", StateType.ONE); ConcreteOriginator anotherOriginator = new ConcreteOriginator("Hola!", StateType.ONE); ConcreteOriginator2 thirdOriginator = new ConcreteOriginator2(7); // Set some state data. myOriginator.Speak(); anotherOriginator.Speak(); thirdOriginator.Speak(); // Save the states into our memento. myOriginator.SaveMemento(memento); anotherOriginator.SaveMemento(memento); thirdOriginator.SaveMemento(memento); // Now change our originators' states. myOriginator.SetData("Goodbye!", StateType.TWO); anotherOriginator.SetData("Adios!", StateType.TWO); thirdOriginator.SetData(99); myOriginator.Speak(); anotherOriginator.Speak(); thirdOriginator.Speak(); // Restore our originator's state. myOriginator.RestoreMemento(memento); anotherOriginator.RestoreMemento(memento); thirdOriginator.RestoreMemento(memento); myOriginator.Speak(); anotherOriginator.Speak(); thirdOriginator.Speak(); Console.ReadKey(); }
Hello World! I'm in state ONE Hola! I'm in state ONE My value is 7 Goodbye! I'm in state TWO Adios! I'm in state TWO My value is 99 Hello World! I'm in state ONE Hola! I'm in state ONE My value is 7
• Crystal Report
• Stimul Report
• Telerik Reporting
• …
در ادامه این سری آموزشها قصد داریم Telerik Reporting و نحوه تهیه گزارش با آن را مورد بررسی قرار دهیم. این ابزار امکانات بسیاری در خصوص تهیه گزارش برنامههای دات نتی نظیر Windows Form ، Asp.net و ... در اختیار ما قرار میدهد.در ادامه و برای شروع ، ساخت یک گزارش ساده در این محیط را بررسی میکنیم.
نکته : گزارشاتی که توسط Telerik Reporting تهیه میشوند به وسیله کدهای C# جنریت میشوند.بنابراین همیشه توصیه میشود گزارشات خود را درون یک یا چند پروژه Class Library قرار دهیم و از این پس ، این گزارشات از درون پروژههای دیگر (ویندوزی ، وب و ...) در دسترس هستند.کافی ست پروژه Class Library را به عنوان Reference به پروژه مورد نظر خود اضافه کنیم.. برای شروع میتوان یک پروژه جدید از نوع Class Library ایجاد کرد.پس از آن روی نام پروژه راست کلیک کنید و گزینه Telerik Report را انتخاب نمایید.پس از تعیین نام گزارش کلید Ok را کلیک نمایید.
در این حالت فایل گزارش به پروژه افزوده میشود. در ادامه میتوانید توسط ویزاردی که نمایش داده میشود کارهای عمومی مربوط به پیاده سازی گزارش (انتخاب منبع داده(Data Source) ، ساخت Query جهت بارگذاری اطلاعات ، فیلدهایی که باید نمایش داده شوند ، گروه بندی دادهها و ...) را توسط این ویزارد انجام دهید. برای اینکار در پنجره ای که نمایش داده میشود بر روی کلید Next کلیک نمایید.
جهت ایجاد یک گزارش جدید در پنجره Report Choose Page گزینه New Report را انتخاب نموده و کلید Next را کلیک نمایید.
جهت انتخاب منبع داده گزارش در پنجره Choose Data Source گزینه Add New Data Source را انتخاب نمایید.در این حالت میتوانید گزینههای متفاوتی را به عنوان منبع داده گزارش خود انتخاب نمایید. گزینههای نمایش داده شده به شرح ذیل است:
• Sql Data Source : جهت اتصال مستقیم به بانک اطلاعات Microsoft Sql Server
• Object Data Source : جهت اتصال به کلاسهای لایه Business و بارگذاری داده از این کلاس ها
• Entity Data Source : جهت اتصال به Entity Framework
• Open Access Data Source : جهت اتصال به Open Access ORM ساخت شرکت Telerik
• Cube Data Source : جهت اتصال و نمایش دادههای تحلیل شده
در ادامه برای اینکه بتوان مستقیما به Sql Server وصل شد و Queryهای مربوط به گزارش را روی آن اجرا نمود؛ میتوان گزینه Sql Data Source را انتخاب نمود و بر روی کلید Ok کلیک کرد.سپس در پنجره Choose Your Data Connection گزینه New Connection را کلیک کنید و یک اتصال به بانک مورد نظر خود ایجاد کنید.پس ایجاد و تست Connection ساخته شده روی Next کلیک کنید.در پنجره Save the connection string میتوان نامی را جهت Connection string انتخاب کرد تا Connection string با همان نام در فایل Config پروژه ذخیره شود.در ادامه کلید Next را کلیک کرده و وارد مرحله بعد شوید. در پنجره Configure Data Source Command گزینه Query Builder را جهت ساخت Query مورد نظر برای بارگذاری دادهها انتخاب نمایید.
پس از ساخت Query مورد نظر کلید Ok را کلیک نمایید. در پنجره Configure Data Source Command کوئری ساخته شده به شما نمایش داده میشود.کلید Next را کلیک کنید.
سپس وارد مرحله Preview Data Source Result میشوید که در آن قادر خواهید بود پیش نمایشی از داده هایی که بعدا توسط Query ساخته شده بارگذاری خواهند شد را مشاهده نمایید. Next را کلیک نموده تا وارد مرحله بعد شوید.مرحله بعد Standard Report Type میباشد که در این مرحله شما میتوانید نوع گزارش خود را انتخاب نمایید و کلید Next را فشار دهید.در بخش Design Data Layout چند فیلد را از بخش سمت چپ (Available Fields) انتخاب نموده و کلید Details را کلیک نمایید.فیلدهای انتخاب شده به بخش Details گزارش اضافه خواهند شد.در ادامه Next را کلیک کنید تا وارد بخش Choose Report Layout شوید.شما میتوانید در این بخش یک حالت نمایشی را برای گزارش خود انتخاب نمایید و Next را کلیک نمایید.در بخش Choose Report Style یک قالب بندی جهت گزارش خود انتخاب نمایید.در ادامه Next و سپس Finish را کلیک نمایید.کدهای گزارش Generate شده میتوان در قسمت Designer گزارش را مشاهده نمود.
در این حالت کارهای زیر توسط Wizard به صورت اتوماتیک انجام خواهد شد:
• بایند شدن اتوماتیک فیلدهای گزارش به ستوانهای مرتبط
• اعمال قالب بندی انتخاب شده برای صفحه و سر ستونها
• افزودن تاریخ و شماره صفحه به پایین گزارش
در ادامه پروژه را Rebuild کرده و گزینه Preview را در Designer جهت نمایش ، پیش نمایش گزارش کلیک نمایید.
• Report Header: مواردی که در این بخش از گزارش قرار میگیرند در بالای صفحه اول گزارش نمایش داده میشوند.
• Page Header: مواردی که در این بخش از گزارش قرار میگیرند در بالای همه صفحات گزارش قرار گرفته و تکرار میشوند.
• Details: دادههای اصلی گزارش که شامل جزئیات و بخش اصلی گزارش میباشند و سطر به سطر نیز تکرار میشوند در این بخش قرار میگیرند.
• Page Footer: مواردی که در این بخش از گزارش قرار میگیرند در پایین همه صفحات نمایش داده میشوند.
• Report Footer:مواردی که در این بخش قرار میگیرند در پایین صفحه آخر گزارش نمایش داده میشوند.
ادامه دارد ...