در حال حاضر توصیهی مایکروسافت ، عدم استفادهی از System.Drawing.Common و جایگزینی آن با یکی از کتابخانههای زیر است:
- SkiaSharp
- Microsoft.Maui.Graphics
البته پیشتر در این لیست توصیه شده، کتابخانهی SixLabors.ImageSharp.Drawing هم وجود داشت که به علت تغییر مجوز آن، به یک مجوز نیمه تجاری، نیمه سورس باز، از لیست فوق حذف شدهاست.
مشکل فارسی نویسی با SkiaSharp
اگر سعی کنیم با استفاده از مثالهای متداول SkiaSharp، یک متن فارسی را نمایش دهیم، به خروجی زیر خواهیم رسید:
// crate a surface var info = new SKImageInfo(256, 256); using var surface = SKSurface.Create(info); // the the canvas and properties var canvas = surface.Canvas; // make sure the canvas is blank canvas.Clear(SKColors.White); // draw some text using var typeface = SKTypeface.FromFamilyName("Tahoma"); using var paint = new SKPaint { Color = SKColors.Black, IsAntialias = true, Style = SKPaintStyle.Fill, TextAlign = SKTextAlign.Center, TextSize = 24, Typeface = typeface, }; var coord = new SKPoint(info.Width / 2, (info.Height + paint.TextSize) / 2); canvas.DrawText("آزمایش", coord, paint); // save the file using var image = surface.Snapshot(); using var data = image.Encode(SKEncodedImageFormat.Png, 100); using var stream = File.OpenWrite("farsi-text-1.png"); data.SaveTo(stream);
<ItemGroup> <PackageReference Include="SkiaSharp" Version="2.88.3" /> </ItemGroup>
همانطور که مشاهده میکنید، حروف فارسی در آن از هم جدا هستند و همچنین از چپ به راست نمایش داده شدهاست.
رفع مشکل فارسی نویسی با SkiaSharp
برای رفع مشکل فوق، نیاز است از افزونهی «حرف باز» این کتابخانه استفاده کرد که روش نصب آن به صورت زیر است:
<ItemGroup> <PackageReference Include="SkiaSharp" Version="2.88.3" /> <PackageReference Include="SkiaSharp.HarfBuzz" Version="2.88.3" /> </ItemGroup>
// crate a surface var info = new SKImageInfo(256, 256); using var surface = SKSurface.Create(info); // the the canvas and properties var canvas = surface.Canvas; // make sure the canvas is blank canvas.Clear(SKColors.White); // draw some text using var typeface = SKTypeface.FromFamilyName("Tahoma"); using var shaper = new SKShaper(typeface); using var paint = new SKPaint { Color = SKColors.Black, IsAntialias = true, Style = SKPaintStyle.Fill, TextAlign = SKTextAlign.Center, TextSize = 24, Typeface = typeface, }; var coord = new SKPoint(info.Width / 2, (info.Height + paint.TextSize) / 2); canvas.DrawShapedText(shaper, "آزمایش", coord, paint); // save the file using var image = surface.Snapshot(); using var data = image.Encode(SKEncodedImageFormat.Png, 100); using var stream = File.OpenWrite("farsi-text-2.png"); data.SaveTo(stream);
مطلبی را در مورد شبیه سازی ارسال ایمیل جهت بررسی خروجی واقعی یک برنامه قبلا نوشته بودم. در تکمیل این مبحث، برنامه رایگان و سورس بازی به نام Antix SMTP Server for Developers نیز وجود دارد که از آدرس زیر قابل دریافت است:
این برنامه به صورت یک پروسه پس زمینه اجرا شده و تواناییهای یک SMTP Server واقعی را شبیه سازی میکند؛ بدون اینکه ایمیلی را ارسال نماید. پس از اجرا، منتظر دریافت ایمیلهای ارسالی از طریق SMTP Client برنامهی شما شده و پس از دریافت ایمیلها، آنها را در پوشهای مشخص ذخیره میکند. همچنین توسط این برنامه میتوان عنوان ایمیلهای ارسالی را نیز مشاهده نمود (مزیت اصلی نسبت به روش قبلی معرفی شده). با دوبار کلیک بر روی ایمیلهای لیست شده، میتوان آنها را در mail client نصب شده مانند آوت لوک، مشاهده نمود. به این صورت یک برنامه نویس میتواند متن و فرمت ایمیلهای ارسالی توسط برنامه خود را پیش از بکارگیری آن در یک محیط واقعی کاری، کاملا بررسی و آزمایش نماید. بدیهی است که این برنامه حتی میتواند بر روی کامپیوتری دیگر در شبکه نیز قرار داشته باشد. همچنین با توجه به نحوهی توزیع ClickOnce این برنامه، هر بار که بسته شود، بررسی خواهد کرد که آیا نگارش جدیدتری از آن آماده شده است یا خیر (اگر نصاب ClickOnce آن را دریافت و نصب کنید).
اگر از دات نت فریم ورک استفاده میکنید، جهت استفاده از این شبیه ساز کافی است app.config و یا web.config برنامه شما به صورت زیر تنظیم شده باشد:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<mailSettings>
<smtp>
<network port="25" host="127.0.0.1"/>
</smtp>
</mailSettings>
</system.net>
</configuration>
پ.ن.
همانطور که در تصویر مشخص است این برنامه قادر به تفسیر عنوان ایمیل فارسی نیست (اولین عنوان بررسی شده فارسی است). اگر وقت کردید در این پروژه سورس باز شرکت کنید و نکته زیر را به آن اعمال نمائید (زیبایی یک کار سورس باز ...):
رمزگشایی عنوان یک ایمیل فارسی دریافت شده
(The God Class Problem (Behavioral Form
یکی از مخاطراتی که ممکن است موجب عدم بروز مزایای شیء گرایی در طرح شما شود، بحث God Class میباشد. شکل رفتاری آن (Behavioral Form) بیشتر در اثر یک خطای مشترک بین توسعه دهندگان پارادایم action-oriented و در جریان مهاجرت به سمت پارادایم شیء گرا، رخ میدهد.
این توسعه دهندگان بیشتر سعی در تسخیر و دستیابی به یک مکانیزم کنترل مرکزی شبیه به آنچه در پارادایم action-oriented داشتهاند، در طراحی شیء گرای خود دارند. حاصل این کار تشکیل کلاسی خواهد بود که همه کارها را انجام میدهد، درحالیکه جزئیات ناچیزی هم به عهده مجموعهای از کلاسها سپرده شده است.
قاعده شهودی 3.1
تا حد ممکن هوشمندی سیستم را به صورت افقی و به طور یکنواخت توزیع کنید. به این معنی که کلاسهای سطح بالای موجود در طراحی، باید کار را به طور یکسان مابین خود به اشتراک بگذارند. (Distribute system intelligence horizontally as uniformly as possible, that is, the top-level classes in a design should share the work uniformly)منظور اینکه Businessای را که سیستم قرار است پیاده سازی کند، بین کلاسهای سطح بالا تقسیم کنید. در حالت vertical یا عمودی میتوان در نظر گرفت که کلاسی این Business را توسط یکسری متد در دل خود پیاده سازی کند و این متدها یکدیگر را فراخوانی خواهند کرد.
قاعده شهودی 3.2
در سیستم خود God Class ایجاد نکنید. به کلاس هایی که نام آنها شامل Driver، Manager و یا Subsystem میباشد، مشکوک باشید. (Do not create god classes/objects in your system. Be very suspicious of a class whose name contains Driver, Manager, System, or Subsystem)
مانند: BlahBlahSystem یا BlahManager
قاعده شهودی 3.3مراقب کلاس هایی باشید که در واسط عمومی آنها تعداد زیادی Accessor Method تعریف شده است؛ وجود آنها نشان از این دارد که داده و رفتار، در یکجا نگه داشته نشده اند. (Beware of classes that have many accessor methods defined in their public interface. Having many implies that related data and behavior are not being kept in one place)ازدیاد عملیات get و set در واسط عمومی کلاسها که Accessor Method نامیده میشوند، نشان دهنده ایجاد شکل رفتاری God Class میباشند. منظور این است که یک کلاس، رفتارهایی برای کار کردن با دادههای خود در نظر نگرفته است و این دادهها را از طریق accessor methodها در اختیار کلاس دیگری قرار میدهد تا عملیات روی دادهها را انجام دهد. در اینجا هم مقصود God Class شدن کلاسی است که از این accessor methodها استفاده میکند و نشان از این دارد که تعداد رفتارهای آن زیاد خواهد شد.
مراقب کلاس هایی باشید که تعداد خیلی زیادی رفتار نامرتبط دارند؛ یعنی رفتارهایی که فقط برروی زیر مجموعه ای از دادههای کلاس کار میکنند. God Classها اغلب دارای اینگونه رفتارهای نامرتبط به هم هستند. (Beware of classes that have too much noncommunicating behavior, that is, methods that operate on a proper subset of the data members of a class. God classes often exhibit much noncommunicating behavior)منظور اینکه کلاس مورد نظر را میتوان شکست و تبدیل به دو کلاس مختلف کرد. به عنوان اولین مثال، دامنه مربوط به سیستم برنامه ریزی دورههای آموزشی را در نظر بگیرید. در این دامنه، ما با وهله هایی از «Student» ،«Course» و «CourseOffering» سروکار خواهیم داشت.
قصد داریم با فراخوانی متد ()add_student مربوط به CourseOffering، یک دانشجو را به لیست شرکت کنندگان یک دوره اضافه کنیم. همچنین در این زمان لازم است مطمئن شویم که دانشجوی مورد نظر تمام پیش نیازهای دوره انتخاب شده را گذرانده باشد. به نظر شما کدام کلاس میبایست عملیات چک کردن پیش نیازها را انجام دهد؟
کلاس دانشجو از دورههایی که گذرانده است آگاه است و کلاس دوره هم از پیش نیازهای خود. در بهترین حالت شاید یکی از طراحیهای زیر را ارائه دهید. به شکلی که یا کلاس دوره با استفاده از متد get_courses مربوط به کلاس دانشجو، داده مورد نیاز را بدست آورده و عملیات چک کردن را در دل خود بگنجاند یا برعکس.
در هر دو طراحی بالا، بخشی از اطلاعات مربوط به policy (سیاست) در کلاس هایی قرار دارد که موضوع تصمیمات سیاستها هستند. این کار از آن جهت که کلاسهای مورد نظر ما را به دامنه خاصی که این policy در آن دامنه معنا دارد وابسته میکند و امکان استفاده مجدد از آن کلاسها را از دست خواهید داد.
راه حلهای پیشنهادی برای مشکل مطرح شده به شکل زیر میباشند:
با توجه به طراحی شکل بالا، یا خود کلاس CourseOffering با استفاده از لیست دورههای گذرانده شده توسط دانشجو و لیست دورههای پیش نیاز دوره انتخابی، چک کردن را انجام دهد و یا کلاسی با عنوان PrereqChecker که یک Controller Class (کلاسی که فقط رفتار دارد و داده مورد نظر خود را توسط سایر کلاسها و از طریق accessor methodهای آنها تأمین میکند) میباشد، وظیفه چک کردن را برعهده بگیرد.
علاوه بر اینکهaccessor method ها، داده را برای کلاسهای کنترلر مهیا میکنند (مانند مثال بالا)، وظیفهی مهیا کردن داده برای UI (رابط کاربری) را نیاز بر عهده خواهند داشت. به این صورت که رابط کاربری، با استفاده از این متدها، مشخصات درونی مدل را نمایش دهد و یا این امکان را به کاربر میدهد که این مشخصات درونی مدل را ویرایش کرده و به سمت مدل ارسال نماید.
قاعده شهودی 3.5
در برنامههایی که شامل یک مدل شی گرایی میباشند که با رابط کاربری تعامل دارند، مدل نباید به رابط کاربری وابسته باشد. رابط کاربری میبایست وابسته به مدل باشد. (In applications that consist of an object-oriented model interacting with a user interface, the model should never be dependent on the interface. The interface should be dependent on the model)
برای عدم نقض این قاعده شهودی، لازم است در مدل یکسری accessor method در نظر گرفته شود تا رابط کاربری از آن استفاده کند؛ ولی باید مراقب بود که این accessor methodها صرفا توسط رابط کاربری استفاده شود و عدم توجه به این قضیه، احتمالا شما را به سمت نقض قاعده 3.3 متمایل خواهد کرد.
کتابخانه glogg
نرم افزاری بسیار سریع با قابلیت باز کردن فایلهای چند گیگابایتی است که با استفاده از regular expressions به راحتی میتوانید در آن جستجو کنید. دانلود
glogg - the fast, smart log explorer
glogg is a multi-platform GUI application that helps browse and search through long and complex log files. It is designed with programmers and system administrators in mind and can be seen as a graphical, interactive combination of grep and less.
Main features
- Runs on Unix-like systems, Windows and Mac thanks to Qt
- Provides a second window showing the result of the current search
- Reads UTF-8 and ISO-8859-1 files
- Supports grep/egrep like regular expressions
- Colorizes the log and search results
- Displays a context view of where in the log the lines of interest are
- Is fast and reads the file directly from disk, without loading it into memory
- Is open source, released under the GPL
سؤالات متداول
- میخواهم برنامهام را بر روی کامپیوتر مشتری بدون دردسر نصب کنم؛ با حداقل حجم و دردسر توزیع. به علاوه بدون نیاز به وصله پینه کردن اسمبلیهای تجاری دریافت شده.
پاسخ: PdfReport از چند اسمبلی دات نتی تشکیل شده است که نیاز به نصب خاصی ندارد. همچنین حجم فشرده شده آن نیز زیر 2 مگابایت است. بنابراین از جهت توزیع مشکل خاصی نخواهید داشت. همچنین کل این مجموعه سورس باز است و مشکلات متداول همراه با گزارش سازهای تجاری را به همراه ندارد.
- میخواهم فایل گزارش، به همراه برنامه و فایل exe آن و نه جدای از آن توزیع شود.
پاسخ: روش کار با PdfReport اصطلاحا code-first است. یعنی یک یا چند کلاس تهیه شده توسط شما، کار تهیه گزارش را انجام میدهند و تمام اینها کامپایل شده و به همراه فایل اجرایی یا اسمبلیهای خاصی که برای آن درنظر میگیرید، کامپایل و توزیع خواهند شد. همچنین با توجه به code-first بودن آن و عدم وابستگی به فناوری خاصی، این گزارشات در برنامههای وب و ویندوز نیز میتوانند بدون نیاز به تغییری در کدهای شما مورد استفاده قرار گیرند.
- برای کار با PdfReport از کجا باید شروع کرد؟
پاسخ: لطفا برچسب PdfReport را در سایت جاری دنبال نمائید. نحوه استفاده از قابلیتهای آن قدم به قدم توضیح داده شدهاند.
- میخواهم برای صرفه جویی در کاغذ چاپی، گزارش چند ستونهای را تهیه کنم.
پاسخ: لطفا مراجعه کنید به مثال ایجاد قالبهای سفارشی ستونها.
- میخواهم گزارشی را تولید کنم که حجم متن فیلدهای آن مشخص نیست. یکی ممکن است نصف صفحه باشد دیگری دو صفحه و یا بعضی تنها یک سطر.
پاسخ: در PdfReport ارتفاع هر سطر به صورت خودکار بر مبنای حجم وارد شده محاسبه و تنظیم میگردد. به عبارتی این تنظیم ثابت نیست و سبب حذف محتوای ارائه شده در آنها یا محو شدن ردیفهای دیگر نمیگردد.
- نیاز به گزارش سازی دارم که بدون مشکل با ORMها کار کند. برای مثال در حین کار با Entity framework مستقیما بتواند با اشیاء و لیستهای حاصل از آن کار کند.
پاسخ: یکی از انواع منابع داده تعریف شده در PdfReport جهت کار با ORMها طراحی شده است که مثالی از نحوه استفاده از آنرا در مثال EF Code first همراه با مجموعه مثالهای این کتابخانه میتوانید ملاحظه نمائید.
- آیا این کتابخانه میتواند از فایل سیستم (و نه صرفا بانک اطلاعاتی) هم تصاویر را دریافت و در گزارشات قرار دهد؟
پاسخ: بلی. لطفا به مثال ImageFilePath مراجعه نمائید.
- میخواهم یک گزارش ساز پویا در برنامه داشته باشم. فقط کوئری غیر مشخصی را به آن بدهم و حاصل آن یک گزارش باشد.
پاسخ: امکان تهیه گزارشهای پویا نیز در PdfReport پیش بینی شده است. توضیحات بیشتر همچنین این امکان در حین کار با ORMها نیز وجود دارد.
- میخواهم بدون استفاده از بانک اطلاعاتی نیز بتوانم گزارشی را تهیه کنم. برای مثال یک لیست جنریک تشکیل شده در حافظه دارم.
پاسخ: برای این منظور تنها کافی است از منبع داده صحیحی استفاده نمائید. برای اطلاعات بیشتر به مثال IList مراجعه کنید.
- میخواهم از بانکهای اطلاعاتی دیگری بجز SQL Server استفاده کنم.
پاسخ: میتوانید یک نمونه مثال استفاده از PdfReport را با بانک اطلاعاتی SQLite، در اینجا مشاهده کنید.
معرفی ELMAH
عموما کاربران نمیتوانند گزارش خطای خوبی را ارائه بدهند و البته انتظاری هم از آنان نیست. تنها گزارشی که از یک کاربر دریافت میکنید این است: "برنامه کار نمیکنه!" و همین!
روشهای متعددی برای لاگ کردن خطاهای یک برنامه ASP.Net موجود است؛ چه خودتان آنها را توسعه دهید و یا از ASP.NET health monitoring استفاده کنید.
روش دیگری که این روزها در وبلاگهای متعددی در مورد آن مطلب منتشر میشود، استفاده از ELMAH است. (البته ELMAH به تازگی منتشر نشده ولی تا کیفیت محصولی به عموم ثابت شود مدتی زمان میبرد)
ELMAH یک ماژول رایگان و سورس باز لاگ کردن خطاهای مدیریت نشده برنامههای ASP.Net است. برای استفاده از این ماژول نیازی نیست تا تغییری در برنامه خود ایجاد کنید یا حتی آنرا کامپایل مجدد نمائید. یک فایل dll دارد به همراه کمی تغییر در web.config برنامه جهت معرفی آن و این تمام کاری است که برای برپایی آن لازم است صورت گیرد. این ماژول تمامی خطاهای مدیریت نشدهی برنامه شما را لاگ کرده (در حافظه سرور، در یک فایل xml ، در یک دیتابیس اس کیوال سرور یا اوراکل ، در یک دیتابیس اکسس و یا در یک دیتابیس اس کیوال لایت) و برای مرور آنها یک صفحهی وب سفارشی یا فیدی مخصوص را نیز در اختیار شما قرار میدهد. همچنین این قابلیت را هم دارد که به محض بروز خطایی یک ایمیل را نیز به شما ارسال نماید.
با توجه به اینکه این ماژول در Google code قرار گرفته احتمالا دسترسی به آن مشکل خواهد بود. سورس و فایلهای کامپایل شده آنرا از آدرسهای زیر نیز میتوان دریافت نمود:
نحوه استفاده از ELMAH :
برای استفاده از ELMAH دو کار را باید انجام دهید:
الف) کپی کردن فایل Elmah.dll در پوشه bin برنامه
ب) تنظیم وب کانفیگ برنامه
بهترین مرجع برای آشنایی با نحوه بکار گیری این ماژول، مراجعه به فایل web.config موجود در پوشه samples آن است. بر اساس این فایل نمونه:
- ابتدا باید configSections آن را به وب کانفیگ خود اضافه کنید.
- سپس تگ elmah باید اضافه شود. در این تگ موارد زیر مشخص میشوند:
الف) آیا خطاها توسط آدرس elmah.axd توسط کاربران راه دور قابل مشاهده شود یا خیر.
ب) خطاها کجا ذخیره شوند؟ موارد زیر پشتیبانی میشوند:
دیتابیسهای اس کیوال سرور ، اوراکل ، حافظه سرور، فایلهای xml ، دیتابیس SQLite ، دیتابیس اکسس و یا دیتابیسی از نوع VistaDB
ج) آیا خطاها ایمیل هم بشوند؟ اگر بلی، تگ مربوطه را تنظیم کنید.
د) آیا خطاها به اکانت twitter شما نیز ارسال شوند؟
- در ادامه تگ مربوط به معرفی این httpModules باید تنظیم شود.
- سپس httpHandlers ایی به نام elmah.axd که جهت مرور خطاها میتوان از آن استفاده نمود معرفی میگردد.
- از IIS7 استفاده میکنید؟ قسمت system.webServer را نیز باید اضافه نمائید.
- و در آخر نحوهی دسترسی به elmah.axd مشخص میشود. اگر اجازه دسترسی از راه دور را داده باشید، به این طریق میشود دسترسی را فقط به کاربران مجاز و تعیین اعتبار شده، اعطاء کرد و یا به نقشی مشخص مانند ادمین و غیره.
برای نمونه، اگر بخواهید از دیتابیس SQLite جهت ذخیره سازی خطاهای حاصل شده استفاده نمائید و نیز از ارسال ایمیل صرفنظر کنید، وب کانفیگ برنامه شما باید به شکل زیر تغییر یابد:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/>
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
<section name="errorTweet" requirePermission="false" type="Elmah.ErrorTweetSectionHandler, Elmah"/>
</sectionGroup>
</configSections>
<elmah>
<security allowRemoteAccess="1" />
<errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="cn1" />
</elmah>
<appSettings/>
<connectionStrings>
<add name="cn1" connectionString="data source=~/ErrorsLog/Errors.db" />
</connectionStrings>
<system.web>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
</httpModules>
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<compilation debug="true"/>
<authentication mode="Windows" />
</system.web>
</configuration>
سادهترین تنظیم این ماژول استفاده از حالت xml است که به ازای هر خطا یک فایل xml را تولید کرده و نیاز به اسمبلی دیگری بجز ماژول مربوطه نخواهد داشت.
تذکر:
از لحاظ امنیتی مثال فوق توصیه نمیشود زیرا allowRemoteAccess آن 1 است و قسمت authorization ذکر نشده است. این مثال فقط جهت راه اندازی و آزمایش اولیه ارائه گردیده است. (همچنین بهتر است این نام پیش فرض را به نامی دیگر مثلا myloggermdl.axd تغییر داده و در قسمت httpHandlers تنظیم نمائید. سپس این نام را به تگ location نیز اضافه کنید)
اکنون برای مشاهده خروجی این ماژول به انتهای آدرس سایت خود، elmah.axd را اضافه کرده و سپس enter کنید:
همانطور که در تصویر مشخص است، تمامی خطاهای لاگ شده گزارش داده شدهاند. همچنین دو نوع فید به همراه امکان دریافت خطاها به صورت CSV نیز موجود است. با کلیک بر روی لینک details ، صفحهی بسیار ارزندهای ارائه میشود که تقریبا نحوهی وقوع ماجرا را بازسازی میکند.
نکتهی مهمی که در صفحهی جزئیات ارائه میشود (علاوه بر stack trace و مشخصات کاربر)، مقادیر تمامی فیلدهای یک صفحه هنگام بروز خطا است (قسمت Raw/Source data in XML or in JSON در این صفحه) :
به این صورت دیگر نیازی نیست از کاربر بپرسید چه چیزی را وارد کرده بودید که خطا حاصل شد. دقیقا مقادیر فیلدهای همان صفحهی زمان بروز خطا نیز برای شما لاگ میگردد.
نکته:
ماژول SQLite ایی که به همراه مجموعه ELMAH ارائه میشود 32 بیتی کامپایل شده (64 بیتی آن نیز موجود است که باید از آن در صورت لزوم استفاده شود). بنابراین برای اینکه در یک سرور 64 بیتی به مشکل برنخورید و خطای BadImageFormat را دریافت نکنید نیاز است تا به این نکته دقت داشت.
برای مطالعه بیشتر:
Error Logging Modules And Handlers
Sending ELMAH Errors Via GMail
Exception-Driven Development
Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components
تنظیمات امنیتی دسترسی به سرور RavenDB
توضیحات بیشتر در اینجا Security system - OSS vs commercial use