نظرات مطالب
مفاهیم برنامه نویسی ـ مروری بر پروپرتی‌ها
ضمن تشکر از پیگیری و پیشنهادهای حضرتعالی و پوزش به جهت طولانی شدن فاصله زمانی ارائه مطالب در مورد پیشنهادهای ارزشمندی که فرمودید باید چند نکته را عرض کنم.
تا حد زیادی معمولاً سعی کردم این موارد محقق بشه. مثلا در مورد همان اکسسور و بیشتر مفاهیم و اصطلاحات مهم، معادل انگلیسی آورده شده است. اصولاً ترجمه برخی مفاهیم را مناسب نمی‌دانم و از طرفی آوردن تعداد زیادی واژه انگلیسی در بین واژگان فارسی سبب کاهش زیبایی متن می‌گردد. بنابراین معمولاً کلمات مهم را یک یا چند بار به صورت انگلیسی بیان می‌کنم و سپس با حروف فارسی می‌نویسم مانند اکسسور تا به صورت روان‌تری در متن قابل خواندن باشد.
همچنین در امر آموزش ابتدا سعی می‌کنم یک دید کلی و از بالا به دانشجو یا خواننده منتقل کنم. در این مرحله تنها جزییات مهم که برای درک موضوع و شروع کار عملی مانند انجام یک پروژه کاربردی لازم است بیان می‌شود. چراکه اگر از ابتدا ذهن را با تعداد زیادی جزییات درگیر کنیم ممکن است در موقع خواندن هر بخش خواننده مفاهیم را درک کند اما پس از پایان مطالب نمی‌داند از کجا باید شروع کند و قدرت استفاده از آموخته‌ها را ندارد. به همین جهت سعی می‌شود بر روی مفاهیم غیر کلیدی کمتر در مراحل اولیه بحث شود.
از طرفی سعی می‌کنم مطالب دارای حجم مناسب و مفاهیم پیوسته ای باشند تا قابل درک بوده و خسته کننده نباشند. مثلاً از آنجاییکه در بخش‌های پیشین مقاله‌ای که به زحمت یکی از دوستان در سایت قرار گرفته بود برای نامگذاری معرفی شد، از تکرار قوانین یاد شده در این مطالب به جهت جلوگیری از طولانی‌تر شدن خودداری کردم.
با توجه به کارگاه‌های عملی ای که برای تثبیت مطالب در نظر گرفته خواهد شد، تا حد زیادی روش‌های بهینه برای پیاده سازی مفاهیم گوناگون معرفی خواهد شد.
نظرات مطالب
ASP.NET Web API - قسمت اول
سلام
می‌خواهم بدانم برای امنیت web api در پروژه های  web form چه کارهایی باید انجام دهیم بیشتر مطالب در مورد mvc هست مثلا Anti-Forgery Tokens برای mvc به راحتی می‌توان استفاده کرد ولی برای web form چکار بهتر است انجام دهیم؟
در اینجا ما مستقیما با دستورات post put و delete کار داریم که اطلاعات بانک اطلاعاتی رو تغییر می‌دهند. حالا چطور می‌توان امنیت رو کاملا تامین کرد ؟
مثلا کاربران شناسایی شده اطلاعات را وارد کنند و اینکه شخصی نتواند با یک دستور ای جکس توسط مرورگر اطلاعات اشتباه در سایت ثبت کند؟ و یا هر مشکل امنیتی دیگری که پیش بیاید؟
مطالب
بررسی نکات دریافت فایل‌های حجیم توسط HttpClient
HttpClient به عنوان جایگزینی برای HttpWebRequest API قدیمی، به همراه NET 4.5. ارائه شد و هدف آن یکپارچه کردن پیاده سازی‌های متفاوت موجود به همراه ارائه را‌ه‌حلی چندسکویی است که از WPF/UWP ، ASP.NET تا NET Core. و iOS/Android را نیز پشتیبانی می‌کند. تمام قابلیت‌های جدید پروتکل HTTP مانند HTTP/2 نیز از این پس تنها به همراه این API ارائه می‌شوند.
در مطلب «روش استفاده‌ی صحیح از HttpClient در برنامه‌های دات نت» با روش استفاده‌ی تک وهله‌ای آن آشنا شدیم. در این مطلب نکات ویژه‌ی دریافت فایل‌های حجیم آن‌را بررسی خواهیم کرد. بدون توجه به این نکات، یا OutOfMemoryException را دریافت خواهید کرد و یا پیش از پایان کار، با خطای Timeout این پروسه به پایان خواهد رسید.


مشکل اول: نیاز به تغییر Timeout پیش فرض

فرض کنید می‌خواهیم فایل حجیمی را با تنظیمات پیش‌فرض HttpClient دریافت کنیم:
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace HttpClientTips.LargeFiles
{
    class Program
    {
        private static readonly HttpClient _client = new HttpClient();

        static async Task Main(string[] args)
        {
            var bytes = await DownloadLargeFileAsync();
        }

        public static async Task<byte[]> DownloadLargeFileAsync()
        {
            Console.WriteLine("Downloading a 4K content - too much bytes.");
            var response = await _client.GetAsync("http://downloads.4ksamples.com/downloads/sample-Elysium.2013.2160p.mkv");
            var bytes = await response.Content.ReadAsByteArrayAsync();
            return bytes;
        }
    }
}
در این حالت باتوجه به اینکه Timeout پیش‌فرض HttpClient به 100 ثانیه تنظیم شده‌است، اگر سرعت دریافت بالایی را نداشته باشید و نتوانید این فایل را پیش از 2 دقیقه دریافت کنید، برنامه با استثنای TaskCancelledException متوقف خواهد شد.
بنابراین اولین تغییر مورد نیاز، تنظیم صریح Timeout آن است:
private static readonly HttpClient _client = new HttpClient
{
    Timeout = Timeout.InfiniteTimeSpan
};


مشکل دوم: دریافت استثنای OutOfMemoryExceptions

روش دریافت پیش‌فرض اطلاعات توسط HttpClient، نگهداری و بافر تمام آن‌ها در حافظه‌ی سیستم است. این روش برای اطلاعات کم حجم، مشکلی را به همراه نخواهد داشت. بنابراین در حین دریافت فایل‌های چندگیگابایتی با آن، حتما با استثنای OutOfMemoryException مواجه خواهیم شد.
namespace HttpClientTips.LargeFiles
{
    class Program
    {
        private static readonly HttpClient _client = new HttpClient
        {
            Timeout = Timeout.InfiniteTimeSpan
        };

        static async Task Main(string[] args)
        {
            await DownloadLargeFileAsync();
        }

        public static async Task DownloadLargeFileAsync()
        {
            Console.WriteLine("Downloading a 4K content. too much bytes.");
            var response = await _client.GetAsync("http://downloads.4ksamples.com/downloads/sample-Elysium.2013.2160p.mkv");
            using (var streamToReadFrom = await response.Content.ReadAsStreamAsync())
            {
                string fileToWriteTo = Path.GetTempFileName();
                Console.WriteLine($"Save path: {fileToWriteTo}");
                using (var streamToWriteTo = File.Open(fileToWriteTo, FileMode.Create))
                {
                    await streamToReadFrom.CopyToAsync(streamToWriteTo);
                }
            }
        }
    }
}
در این حالت برای رفع مشکل، از متد ReadAsStreamAsync آن استفاده می‌کنیم. به این ترتیب بجای یک آرایه‌ی بزرگ از بایت‌ها، با استریمی از آن‌ها سر و کار داشته و به این صورت مشکل مواجه شدن با کمبود حافظه برطرف می‌شود.
مشکل: در این حالت اگر برنامه را اجرا کنید، تا پایان کار متد DownloadLargeFileAsync، حجم فایل دریافتی تغییری نخواهد کرد. یعنی هنوز هم کل فایل در حافظه بافر می‌شود و سپس استریم آن در اختیار FileStream نهایی برای نوشتن قرار خواهد گرفت.
علت این‌جا است که متد client.GetAsync تا زمانیکه کل Response ارسالی از طرف سرور خوانده نشود (headers + content)، عملیات را سد کرده و منتظر می‌ماند. بنابراین با این تغییرات عملا به نتیجه‌ی دلخواه نرسیده‌ایم.


دریافت اطلاعات Header و سپس استریم کردن Content

چون متد client.GetAsync تا دریافت کامل headers + content متوقف می‌ماند، می‌توان به آن اعلام کرد تنها هدر را به صورت کامل دریافت کن و سپس باقیمانده‌ی عملیات دریافت بدنه‌ی Response را به صورت Stream در اختیار ادامه‌ی برنامه قرار بده. برای اینکار نیاز است پارامتر HttpCompletionOption را تکمیل کرد:
var response = await _client.GetAsync(
                "http://downloads.4ksamples.com/downloads/sample-Elysium.2013.2160p.mkv",
                HttpCompletionOption.ResponseHeadersRead);
پارامتر HttpCompletionOption.ResponseHeadersRead به متد GetAsync اعلام می‌کند که پس از خواندن هدر Response، ادامه‌ی عملیات را در اختیار سطرهای بعدی کد قرار بده و عملیات را تا پایان خواندن کامل Response در حافظه، متوقف نکن.


مشکل سوم: برنامه در دریافت سومین فایل از یک سرور هنگ می‌کند.

تعداد اتصالات همزمانی را که می‌توان توسط HttpClient به یک سرور گشود، محدود هستند. برای مثال این عدد در Full .NET Framework مساوی 2 است. بنابراین اگر اتصال سوم موازی را شروع کنیم، چون Timeout را به بی‌نهایت تنظیم کرده‌ایم، این قسمت از برنامه هیچگاه تکمیل نخواهد شد.
روش تنظیم تعداد اتصالات مجاز به یک سرور:
- در Full .NET Framework با تنظیم خاصیت ServicePointManager.DefaultConnectionLimit است که به 2 تنظیم شده‌است.
- این مورد در NET Core. توسط پارامتر HttpClientHandler و خاصیت MaxConnectionsPerServer آن تنظیم می‌شود:
private static readonly HttpClientHandler _handler = new HttpClientHandler
{
    MaxConnectionsPerServer = int.MaxValue, // default for .NET Core
    UseDefaultCredentials = true
};
private static readonly HttpClient _client = new HttpClient(_handler)
{
    Timeout = Timeout.InfiniteTimeSpan
};
البته مقدار پیش‌فرض آن int.MaxValue است که نسبت به حالت Full .NET Framework عدد بسیار بزرگتری است.
نظرات مطالب
PersianDatePicker یک DatePicker شمسی به زبان JavaScript که از تاریخ سرور استفاده می‌کند

این پروژه یک فایل اسکریپت بیشتر نیست. بنابراین برای کار کردن نیاز به الحاق آن به صفحه هست (مثل تمام پروژه‌های جاوا اسکریپتی). ضمنا این مطلب رو برای سؤال پرسیدن باید رعایت کنی: آناتومی یک گزارش خطای خوب . کسی نمی‌دونه این ارور می‌ده یعنی چی؟ چه خطایی می‌ده؟ کسی مونیتورت رو نمی‌تونه از راه دور ببینه. باید توضیح بدی. تشریحش کنی با کمک این ابزار: نحوه استفاده از افزونه Firebug برای دیباگ برنامه‌های ASP.NET مبتنی بر jQuery        

بازخوردهای دوره
نگاهی به SignalR Clients
جناب آقای نصیری هرکاری کردم جواب نگرفتم. ممنون میشم راهنمایی بفرمائید.

نظرات مطالب
مدیریت سفارشی سطوح دسترسی کاربران در MVC
گاهی اوقات مشکل از اینجا است که ما به صرف شنیده‌ها و پس زمینه‌های فکری، پیچیده‌ترین روش‌ها رو پیاده سازی می‌کنیم تا اون پس زمینه‌ی فکری رو سرکوب کنیم. پایگاه‌های داده‌ی امروزی بسیار قدرتمند و پخته هستند و اگر قرار هست با یک Connection اضافه کل سیستم زیر سوال بره، بهتره بساط اون پایگاه داده جمع بشه.
من فکر می‌کنم باید حالت‌های دیگه ای رو هم بررسی کنی. مثلاً اینکه تغییر در  نقش کاربر بوده یا مجوزهای نقش. اگر کاربر در حین پر کردن یک فرم AJAXیی مجوزش گرفته شد چه واکنشی باید رخ بده؟ آیا تمامی این بررسی‌ها و پیاده سازی اونها، به ایجاد یک ارتباط ساده و واکشی مجوز جاری کاربر برای درخواست برتری دارند؟
اگر امکانش رو داری، یک بررسی زمانی بین اون سیستم مدیریت Cache (با در نظر گرفتن تمامی حالت ها) و ایجاد ارتباط ساده با پایگاه داده برای بررسی داشتن مجوز کاربر انجام بده. 
نظرات مطالب
تکرار خودکار سرستون‌های یک جدول در صفحات مختلف، توسط iTextSharp
با سلام و ممنون از مطالب بسیار خوبتون در مورد itextsharp
در این مثال اگر جدول مثلا چهار ستونه باشه و هدر ، فوتر هر کدام سه ستون.به چه صورت خواهد بود؟
ممنونم میشم اگه راهنماییم کنید.
مطالب
آشنایی با CLR: قسمت بیست و دوم
در ادامه قسمت قبلی، به خصوصیات و ویژگی‌های اسمبلی قوی می‌پردازیم:

اسمبلی‌های نام قوی در برابر دستکاری مقاوم هستند
از آنجائیکه محتویات اسمبلی، هش شده و مقدار هش آن امضا می‌شود، در نتیجه اگر شخصی به دستکاری اسمبلی اقدام کرده باشد یا اینکه فایل مد نظر آسیب دیده باشد، به راحتی قابل شناسایی است و آن اسمبلی به عنوان اسمبلی صحیح شناسایی نخواهد شد و نمی‌گذارد در GAC ثبت شود.

موقعیکه برنامه نیاز داشته باشد به اسمبلی نام قوی بایند یا متصل شود، از 4 ویژگی گفته شده‌ی در قسمت قبلی استفاده می‌کند تا آن را در GAC بیابد. اگر اسمبلی درخواستی موجود باشد، زیر دایرکتوری آن برگشت داده خواهد شد؛ ولی اگر آن را نیابد، ابتدا در داخل دایرکتوری برنامه و سپس در مسیرهایی که در فایل پیکربندی ذکر شده‌اند، به دنبال آن خواهد گشت و در نهایت اگر برنامه توسط فایل MSI نصب شده باشد، محل‌های توزیع را از طریق آن جویا خواهد شد و اگر باز به نتیجه‌ای نرسد، اتصال ناموفق گزارش شده و خطای زیر را ایجاد خواهد کرد:
System.IO.FileNotFoundException
هر بار که برنامه اسمبلی را از غیر از مسیر GAC بخواند، ابتدا هش آن اعتبارسنجی می‌شود و اگر هش آن غیرقابل شناسایی باشد، خطای زیر را صادر می‌کند:
System.IO.FileLoadExceptio
یک اسمبلی با نام قوی مزایای زیر را به همراه دارد:
  1. جلوگیری از دستکاری و حفظ امنیت آن
  2. این اسمبلی تنها یکبار از حافظه‌ی فیزیکی استفاده میکند؛ برعکس توزیع خصوصی که برای هر برنامه باید یک فضای دیسکی داشته باشد.
  3. توزیع ساده‌تر برای نسخه‌های آینده فراهم می‌شود که بعدا در مورد آن توضیح می‌دهیم.
با این حال GAC، یک سیستم امنیتی است که تنها باید توسط مدیر سیستم کنترل شود و هم اینکه توزیع آن‌ها به راحتی توزیع اسمبلی‌های خصوصی نیست. توصیه می‌شود که از اسمبلی‌های نام قوی، زمانی در GAC استفاده کنید که نیاز است توسط چندین برنامه به طور مشترک استفاده شود؛ در غیر این صورت از همان شیوه‌ی توزیع خصوصی استفاده شود. چون در این حالت هم بهترین حالت ایزوله بودن مهیاست، هم نصب آن ساده‌تر است و از آنجا که محل GAC در شاخه system32 است مرتبا از فضای دیسک آن ناحیه کم می‌شود.

سیاست‌های انتخاب اسمبلی توسط GAC
موقعی که GAC می‌خواهد یک اسمبلی را برای برنامه شما بازگرداند، از روی خصوصیاتی چون نام اسمبلی، ورژن، فرهنگ، توکن کلید عمومی و در نهایت بسته به معماری ماشین، یک اسمبلی را برمی‌گرداند. در صورتیکه اسمبلی خاصی را برای ماشین مورد نظر پیدا نکند، از اسمبلی یک ماشین دیگر استفاده خواهد کرد. در واقع این انتخاب، یک سیاست پیش فرض است که می‌تواند از طریق ناشر یا مدیر سیستم تغییر پیدا کند و رونویسی شود.
 

کنترل مدیریت پیشرفته (پیکربندی)
در قسمت بیستم با ساخت فایل پیکریندی و نحوه تنظیم کردن اسکن اسمبلی‌ها در CLR آشنا شدیم. این بار قصد داریم در مورد المان‌های دیگر این فایل پیکریندی صحبت کنیم. فایل پیکربندی زیر را بررسی می‌کنیم:
 
<?xml version="1.0"?>
  <configuration>
     <runtime>
        <assemblyBinding xmlns="urn:schemas­microsoft­com:asm.v1">
           <probing privatePath="AuxFiles;bin\subdir" />
             <dependentAssembly>
                <assemblyIdentity name="SomeClassLibrary"  publicKeyToken="32ab4ba45e0a69a1" culture="neutral"/>
                <bindingRedirect  oldVersion="1.0.0.0" newVersion="2.0.0.0" />
                <codeBase version="2.0.0.0"  href="http://www.Wintellect.com/SomeClassLibrary.dll" />
             </dependentAssembly>
             <dependentAssembly>
                <assemblyIdentity name="TypeLib"  publicKeyToken="1f2e74e897abbcfe" culture="neutral"/>
                <bindingRedirect   oldVersion="3.0.0.0­3.5.0.0" newVersion="4.0.0.0" />
                <publisherPolicy apply="no" />
             </dependentAssembly> 
         </assemblyBinding>
     </runtime> 
 </configuration>
 Probing  در قسمت بیستم گفتیم که در این المان، مکان‌هایی را که CLR برای پیدا کردن اسمبلی‌های با نام ضعیف، باید اسکن کند، وارد می‌کنیم که هر مسیر با , از هم جدا شده‌است. برای اسمبلی‌های با نام قوی CLR باید داخل GAC را نگاه کند و در URL هایی که از طریق المان CodeBase مشخص کرده‌ایم. اگر المان CodeBase مشخص نشود، CLR برای پیدا کردن اسمبلی‌های با نام قوی، داخل دایرکتوری‌های این المان را اسکن خواهد کرد.
 Dependent Assembly اول
 در اولین فرزند این المان، Assembly Identity یک اسمبلی با مشخصاتی مثل Culture و توکن عمومی معرفی می‌شود و در BindingRedirect به CLR اطلاع می‌دهد موقعی که به دنبال نسخه یک این اسمبلی است، نسخه‌ی دو آن را برای استفاده جایگزین کند.
 Code Base
 این المان می‌گوید که وقتی CLR سعی در پیدا کردن نسخه‌ی 2 اسمبلی را دارد، آن را از طریق آدرس مورد نظر پیدا کند. این المان میتواند برای اسمبلی‌های با نام ضعیف هم کار کند.
  Dependent Assembly دوم  این مورد هم همانند سابق است با این تفاوت که گستره‌ی نسخه 3 تا 3.5 را به نسخه‌ی 4 تغییر میدهد.
Publisher Policy
اگر سازمان تولید کننده این اسمبلی فایلی برای تعیین Policy به همراه اسمبلی ارائه کرده باشد، این المان باعث می‌شود این فایل ندیده گرفته شود (در مورد فایل Policy در آینده صحبت می‌کنیم).
اکنون هر موقع CLR ارجاعی از جدول AssemblyDef را برای بارگذاری یک اسمبلی دریافت کند، ابتدا فایل پیکربندی را بررسی میکند و بر اساس آن اسمبلی مورد نظر را بارگذاری خواهد کرد. در این لحظه اسمبلی مورد نظر در GAC وجود دارد و آن را بار می‌کند؛ یا اگر یافت نشد المان CodeBase را بررسی میکند و اگر این المان تعریف نشده باشد، در ادامه سیاست‌های قبلی، پوشه کاری برنامه و دایرکتوری‌های private را اسکن میکند.

با وجود این حالت اگر فرض کنیم مدیر یک سیستم متوجه شود که اسمبلی برنامه دچار مشکل شده است و با ناشر تماس بگیرد و ناشر نسخه‌ی جدیدی از آن اسمبلی را در اختیار او بگذارد، مدیر سیستم می‌تواند به راحتی از طریق فایل پیکربندی، CLR را به استفاده‌ی از اسمبلی جدید به جای اسمبلی قدیمی هدایت کند.

نکته : اگر مدیر بخواهد تمام برنامه‌های موجود از این اسمبلی جدید استفاده کنند باید فایل machine.config را ویرایش کند.

مطالب
NHibernate 3.0 و خواص تنبل (lazy properties)!

احتمالا مطلب "دات نت 4 و کلاس Lazy" را پیشتر مطالعه کرده‌اید. هر چند NHibernate 3.0 بر اساس دات نت فریم ورک 3 و نیم تهیه شده، اما شبیه به این مفهوم را در مورد بارگذاری به تاخیر افتاده‌ی مقادیر خواص یک کلاس که به ندرت مورد استفاده قرار می‌گیرند، پیاده سازی کرده است. Lazy را در اینجا تنبل، به تعویق افتاده، با تاخیر و شبیه به آن می‌توان ترجمه کرد؛ خواص معوقه!
برای مثال فرض کنید یکی از خواص کلاس مورد استفاده، متن، تصویر یا فایلی حجیم است. در مکانی هم که قرار است وهله‌ای از این کلاس مورد استفاده قرار گیرد نیازی به این اطلاعات حجیم نیست؛ با سایر خواص آن سر و کار داریم و نیازی به اشغال حافظه و منابع سیستم در این مورد خاص نیست.

سؤال: چگونه آن‌را تعریف کنیم؟
اگر از NHibernate سنتی استفاده می‌کنید (یا به عبارتی فایل‌های hbm.xml را دستی تهیه می‌کنید)، ویژگی Lazy را به صورت زیر می‌توان مشخص کرد:
<property name="Text" lazy="true"/>
اگر از Fluent NHibernate استفاده می‌کنید (و فایل‌های hbm.xml به صورت خودکار از کلاس‌های شما تهیه خواهند شد)، روش کار به صورت زیر است (فراخوانی متد LazyLoad روی خاصیت مورد نظر):
public class Post
{
public virtual int Id { set; get; }
public virtual string PostText { set; get; }
}

public class PostMappings : ClassMap<Post>
{
public PostMappings()
{
Id(p => p.Id, "PostId").GeneratedBy.Identity();
Map(p => p.PostText).LazyLoad();
//…
Table("Posts");
}
}
در این حالت در پشت صحنه در مورد خاصیت PostText چنین نگاشتی تعریف خواهد شد:
<property name="PostText" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" lazy="true" />

سؤال: چه زمانی نباید از این روش استفاده کرد؟
فرض کنید در شرایطی دیگر نیاز است تا اطلاعات تمام رکوردهای جدول مذکور به همراه مقدار PostText نمایش داده شود. در این حالت بسته به تعداد رکوردها، ممکن است هزاران هزار کوئری به دیتابیس ایجاد شود که مطلوب نیست (به ازای هربار دسترسی به خاصیت PostText یک کوئری تولید می‌شود).

البته امکان لغو موقت این روش تنها در حین استفاده از HQL (یکی دیگر از روش‌های دسترسی به داده‌ها در NHibernate) میسر است. اطلاعات بیشتر: (+)