مطالب
محدود سازی نرخ دسترسی به منابع در برنامه‌های ASP.NET Core - قسمت اول - بررسی مفاهیم
به ASP.NET Core 7، یک میان‌افزار جدید به نام Rate limiter اضافه شده‌است که امکان محدود سازی دسترسی به منابع برنامه‌ی ما را میسر می‌کند. این میان‌افزار، طراحی جامع و مفصلی را دارد. به همین جهت نیاز است در ابتدا با مفاهیم مرتبط با آن آشنا شد و سپس به سراغ پیاده سازی و استفاده‌ی از آن رفت.


چرا باید میزان دسترسی به منابع یک برنامه‌ی وب را محدود کرد؟

فرض کنید در حال ساخت یک web API هستید که کارش ذخیره سازی لیست وظایف اشخاص است و برای مثال از یک GET /api/todos برای دریافت لیست ظایف، یک POST /api/todos برای ثبت و یک PUT /api/todos/{id} برای تغییر موارد ثبت شده، تشکیل می‌شود.
سؤال: چه مشکلی ممکن است به همراه این سه endpoint بروز کند؟
پاسخ: به حداقل چهار مورد زیر می‌توان اشاره کرد:
- یک مهاجم سعی می‌کند با برنامه‌ای که تدارک دیده، هزاران وظیفه‌ی جدید را در چند ثانیه به سمت برنامه ارسال کند تا سبب خاتمه‌ی سرویس آن شود.
- برنامه‌ی ما در حین سرویس دهی، به یک سرویس ثالث نیز وابسته‌است و آن سرویس ثالث، اجازه‌ی استفاده‌ی بیش از اندازه‌ی از منابع خود را نمی‌دهد. با رسیدن تعداد زیادی درخواست به برنامه‌ی ما تنها از طرف یک کاربر، به سقف مجاز استفاده‌ی از آن سرویس ثالث رسیده‌ایم و اکنون برنامه، برای تمام کاربران آن قابل استفاده نیست.
- شخصی در حال دریافت اطلاعات تک تک کاربران است. از شماره یک شروع کرده و به همین نحو جلو می‌رود. برای دریافت اطلاعات کاربران، نیاز است شخص به سیستم وارد شده و اعتبارسنجی شود؛ یعنی به ازای هر درخواست، یک کوئری نیز به سمت بانک اطلاعاتی جهت بررسی وضعیت فعلی و آنی کاربر ارسال می‌شود. به همین جهت عدم کنترل میزان دسترسی به لیست اطلاعات کاربران، بار سنگینی را به بانک اطلاعاتی و CPU سیستم وارد می‌کند.
- هم اکنون چندین موتور جستجو و بات‌هایی نظر آن‌ها در حال پیمایش سایت و برنامه‌ی شما هستند که هر کدام از آن‌ها می‌توانند در حد یک مهاجم رفتار کنند.

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


محدود کردن نرخ دسترسی به برنامه چیست؟

Rate limiting و یا نام دیگر آن request throttling، روشی است که توسط آن بتوان از الگوهای پیش بینی نشده‌ی استفاده‌ی از برنامه جلوگیری کرد. عموما برنامه‌های وب، محدود کردن نرخ دسترسی را بر اساس تعداد بار درخواست انجام شده‌ی در یک بازه‌ی زمانی مشخص، انجام می‌دهند و یا اگر کار برنامه‌ی شما ارائه‌ی فیلم‌های ویدیویی است، شاید بخواهید میزان حجم استفاده شده‌ی توسط یک کاربر را کنترل کنید. در کل هدف نهایی از آن، کاهش و به حداقل رساندن روش‌های آسیب زننده‌ی به برنامه و سیستم است؛ صرفنظر از اینکه این نحوه‌ی استفاده‌ی خاص، سهوی و یا عمدی باشد.


محدود کردن نرخ دسترسی را باید به چه منابعی اعمال کرد؟

پاسخ دقیق به این سؤال: «همه چیز» است! بله! همه چیز را کنترل کنید! در اینجا منظور از همه چیز، همان endpointهایی هستند که استفاده‌ی نابجای از آن‌ها می‌توانند سبب کند شدن برنامه یا از دسترس خارج شدن آن شوند. برای مثال هر endpoint‌ای که از CPU، حافظه، دسترسی به دیسک سخت، بانک اطلاعاتی، APIهای ثالث و خارجی و امثال آن استفاده می‌کند، باید کنترل و محدود شود تا استفاده‌ی ناصحیح یک کاربر از آن‌ها، استفاده‌ی از برنامه را برای سایر کاربران غیرممکن نکند. البته باید دقت داشت که هدف از اینکار، عصبی کردن کاربران عادی و معمولی برنامه نیست. هدف اصلی در اینجا، تشویق به استفاده‌ی منصفانه از منابع سیستم است.


الگوریتم‌های محدود کردن نرخ دسترسی

پیاده سازی ابتدایی محدود کردن نرخ دسترسی به منابع یک برنامه کار مشکلی است و در صورت استفاده از الگوریتم‌های متداولی مانند تعریف یک جدول که شامل user-id، action-id و timestamp، به همراه یکبار ثبت اطلاعات به ازای هر درخواست و همچنین خواندن اطلاعات موجود است که جدول آن نیز به سرعت افزایش حجم می‌دهد. به همین جهت تعدادی الگوریتم بهینه برای اینکار طراحی شده‌اند:

الگوریتم‌های بازه‌ی زمانی مشخص

در این روش، یک شمارشگر در یک بازه‌ی زمانی مشخص فعال می‌شود و بر این مبنا است که محدودیت‌ها اعمال خواهند شد. یک مثال آن، مجاز دانستن فقط «100 درخواست در یک دقیقه» است که نام دیگر آن «Quantized buckets / Fixed window limit» نیز هست.
برای مثال «نام هر اکشن + یک بازه‌ی زمانی»، یک کلید دیکشنری نگهدارنده‌ی اطلاعات محدود کردن نرخ دسترسی خواهد بود که به آن کلید، «bucket name» هم می‌گویند؛ مانند مقدار someaction_106062120. سپس به ازای هر درخواست رسیده، شمارشگر مرتبط با این کلید، یک واحد افزایش پیدا می‌کند و محدود کردن دسترسی‌ها بر اساس مقدار این کلید صورت می‌گیرد. در ادامه با شروع هر بازه‌ی زمانی جدید که در اینجا window نام دارد، یک کلید یا همان «bucket name» جدید تولید شده و مقدار متناظر با این کلید، به صفر تنظیم می‌شود.
اگر بجای دیکشنری‌های #C از بانک اطلاعاتی Redis برای نگهداری این key/valueها استفاده شود، می‌توان برای هر کدام از مقادیر آن، طول عمری را نیز مشخص کرد تا خود Redis، کار حذف خودکار اطلاعات غیرضروری را انجام دهد.

یک مشکل الگوریتم‌های بازه‌ی زمانی مشخص، غیر دقیق بودن آن‌ها است. برای مثال فرض کنید که به ازای هر 10 ثانیه می‌خواهید تنها اجازه‌ی پردازش 4 درخواست رسیده را بدهید. مشکل اینجا است که در این حالت یک کاربر می‌تواند 5 درخواست متوالی را بدون مشکل ارسال کند؛ 3 درخواست را در انتهای بازه‌ی اول و دو درخواست را در ابتدای بازه‌ی دوم:


به یک بازه‌ی زمانی مشخص، fixed window و به انتها و ابتدای دو بازه‌ی زمانی مشخص متوالی، sliding window می‌گویند. همانطور که در تصویر فوق هم مشاهده می‌کنید، در این اگوریتم، امکان محدود سازی دقیقی تنها در یک fixed window میسر است و نه در یک sliding window.

سؤال: آیا این مساله عدم دقت الگوریتم‌های بازه‌ی زمانی مشخص مهم است؟
پاسخ: بستگی دارد! اگر هدف شما، جلوگیری از استفاده‌ی سهوی یا عمدی بیش از حد از منابع سیستم است، این مساله مشکل مهمی را ایجاد نمی‌کند. اما اگر دقت بالایی را انتظار دارید، بله، مهم است! در این حالت از الگوریتم‌های «sliding window limit » بیشتر استفاده می‌شود که در پشت صحنه از همان روش استفاده‌ی از چندین fixed window کوچک، کمک می‌گیرند.


الگوریتم‌های سطل توکن‌ها (Token buckets)

در دنیای مخابرات، از الگوریتم‌های token buckets جهت کنترل میزان مصرف پهنای باند، زیاد استفاده می‌شود. از واژه‌ی سطل در اینجا استفاده شده، چون عموما به همراه آب بکارگرفته می‌شود:
فرض کنید سطل آبی را دارید که در کف آن نشتی دارد. اگر نرخ پر کردن این سطل، با آب، از نرخ نشتی کف آن بیشتر باشد، آب از سطل، سرریز خواهد شد. به این معنا که با سرریز توکن‌ها یا آب در این مثال، هیچ درخواست جدید دیگری پردازش نمی‌شود؛ تا زمانیکه مجددا سطل، به اندازه‌ای خالی شود که بتواند توکن یا آب بیشتری را بپذیرد.

یکی از مزیت‌های این روش، نداشتن مشکل عدم دقت به همراه بازه‌های زمانی مشخص است. در اینجا اگر تعداد درخواست زیادی به یکباره به سمت برنامه ارسال شوند، سطل پردازشی آن‌ها سرریز شده و دیگر پردازش نمی‌شوند.
مزیت دیگر آن‌ها، امکان بروز انفجاری یک ترافیک (bursts in traffic) نیز هست. برای مثال اگر قرار است سطلی با 60 توکن در دقیقه پر شود و این سطل نیز هر ثانیه یکبار تخلیه می‌شود، کلاینت‌ها هنوز می‌توانند 60 درخواست را در طی یک ثانیه ارسال کنند (ترافیک انفجاری) و پس از آن نرخ پردازشی، یک درخواست به ازای هر ثانیه خواهد شد.


آیا باید امکان بروز انفجار در ترافیک را داد؟

عموما در اکثر برنامه‌ها وجود یک محدود کننده‌ی نرخ دسترسی کافی است. برای مثال یک محدود کننده‌ی نرخ دسترسی سراسری 600 درخواست در هر دقیقه، برای هر endpoint ای شاید مناسب باشد. اما گاهی از اوقات نیاز است تا امکان بروز انفجار در ترافیک (bursts) را نیز درنظر گرفت. برای مثال زمانیکه یک برنامه‌ی موبایل شروع به کار می‌کند، در ابتدای راه اندازی آن تعداد زیادی درخواست، به سمت سرور ارسال می‌شوند و پس از آن، این سرعت کاهش پیدا می‌کند. در این حالت بهتر است چندین محدودیت را تعریف کرد: برای مثال امکان ارسال 10 درخواست در هر ثانیه و حداکثر 3600 درخواست در هر ساعت.


روش تشخیص کلاینت‌ها چگونه باشد؟

تا اینجا در مورد bucket name یا کلید دیکشنری اطلاعات محدود کردن دسترسی به منابع، از روش «نام هر اکشن + یک بازه‌ی زمانی» استفاده کردیم. به این کار «پارتیشن بندی درخواست‌ها» هم گفته می‌شود. روش‌های دیگری نیز برای انجام اینکار وجود دارند:
پارتیشن بندی به ازای هر
- endpoint
- آدرس IP. البته باید دقت داشت که کاربرانی که در پشت یک پروکسی قرار دارند، از یک IP آدرس اشتراکی استفاده می‌کنند.
- شماره کاربری. البته باید در اینجا بحث کاربران اعتبارسنجی نشده و anonymous را نیز مدنظر قرار داد.
- شمار سشن کاربر. در این حالت باید بحث ایجاد سشن‌های جدید به ازای دستگاه‌های مختلف مورد استفاده‌ی توسط کاربر را هم مدنظر قرار داد.
- نوع مروگر.
- هدر ویژه رسیده مانند X-Api-Token

بسته به نوع برنامه عموما از ترکیبی از موارد فوق برای پارتیشن بندی درخواست‌های رسیده استفاده می‌شود.


درنظر گرفتن حالت‌های استثنائی

هرچند همانطور که عنوان شد تمام قسمت‌های برنامه باید از لحاظ میزان دسترسی محدود شوند، اما استثناءهای زیر را نیز باید درنظر گرفت:
- عموما تیم مدیریتی یا فروش برنامه، بیش از سایر کاربران، با برنامه کار می‌کنند.
- بیش از اندازه محدود کردن Web crawlers می‌تواند سبب کاهش امتیاز SEO سایت شما شود.
- گروه‌های خاصی از کاربران برنامه نیز می‌توانند دسترسی‌های بیشتری را خریداری کنند.


نحوه‌ی خاتمه‌ی اتصال و درخواست

اگر کاربری به حد نهایی استفاده‌ی از منابع خود رسید، چه باید کرد؟ آیا باید صرفا درخواست او را برگشت زد یا اطلاعات بهتری را به او نمایش داد؟
برای مثال GitHub یک چنین خروجی را به همراه هدرهای ویژه‌ای جهت مشخص سازی وضعیت محدود سازی دسترسی به منابع و علت آن‌، ارائه می‌دهد:
> HTTP/2 403
> Date: Tue, 20 Aug 2013 14:50:41 GMT
> x-ratelimit-limit: 60
> x-ratelimit-remaining: 0
> x-ratelimit-used: 60
> x-ratelimit-reset: 1377013266
> {
> "message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
> "documentation_url": "https://docs.github.com/rest/overview/resources-in-the-rest-api#rate-limiting"
> }
بنابراین بسته به نوع خروجی برنامه که اگر خروجی آن یک API از نوع JSON است و یا یک صفحه‌ی HTML، می‌توان از ترکیبی از هدرها و اطلاعات متنی و HTML استفاده کرد.
حتی یکسری از APIها از status codeهای ویژه‌ای مانند 403 (دسترسی ممنوع)، 503 (سرویس در دسترس نیست) و یا 429 (تعداد درخواست‌های زیاد) برای پاسخ دهی استفاده می‌کنند.



محل ذخیره سازی اطلاعات محدود سازی دسترسی به منابع کجا باشد؟

اگر محدودسازی دسترسی به منابع، جزئی از مدل تجاری برنامه‌ی شما است، نیاز است حتما از یک بانک اطلاعاتی توزیع شده مانند Redis استفاده کرد تا بتواند اطلاعات تمام نمونه‌های در حال اجرای برنامه را پوشش دهد. اما اگر هدف از این محدود سازی تنها میسر ساختن دسترسی منصفانه‌ی به منابع آن است، ذخیره سازی آن‌ها در حافظه‌ی همان نمونه‌ی در حال اجرای برنامه هم کافی است.
مطالب
نگاهی به تاریخچه‌ی زبان #C
این قهرمان ما از سال ۲۰۰۲ سفر خودش را همراه با Visual Studio 2002 شروع کرد و تا الان (۲۰۲۳) حدود ۱۱ بار آپدیت‌های جدید و عالی‌ای را ارائه داده‌است. در اوایل کار، زبانی شبیه به Java بود و صرفا نسبت به زبان‌های سطح پایین، تنها چیزی که اضافه داشت، بحث شی‌ءگرایی بود، اما در ادامه وارد عصر‌های مختلفی شد که بد نیست نگاهی به آن‌ها داشته باشیم. 

عصر نخستین: تبدیل شدن به یک زبان قابل قبول
C# 1.0, C# 1.2, C# 2.0
در این عصر، زبانی را مشاهده می‌کنیم که تقریبا مانند بقیه‌ی زبان‌های C-Base هست و تفاوت چندانی نمی‌کند. می‌شود گفت اینجا کار کردن با انواع داده‌ها نسبت به بقیه زبان‌ها آسان‌تر است. با قابلیت‌های شی‌ءگرایی شروع کرده و در ادامه ویژگی‌های دیگری را هم در ورژن‌های بعدی خود ارائه داد.

عصر دوم: اضافه شدن امکانات منحصر بفرد
C# 3.0 , C# 4.0, C# 5.0
حدود سال ۲۰۰۷، قهرمان ما تصمیم گرفت امکانات منحصر بفردی را ارائه دهد که این زبان را نسبت به بقیه‌ی هم ردیف‌های خودش متمایز کند. این امکانات همراه با NET Framework version 3.5 و Visual Studio 2008 وارد بازار شدند. امکانات نام آشنایی از قبیل Lambda expression ها،Object and collection initializer‌ها و ... در این ورژن به سی‌شارپ اضافه شدند.

عصر سوم: باز نویسی کامل کامپایلر با سی‌شارپ (Roslyn)
سال ۲۰۱۵ سی‌شارپ ۶ همراه با Visual Studio 2015 وارد بازار شد. اینبار سی‌شارپ شروع به اعمال تغییراتی کرد که عمدتا با ذهنیت کد تمیز و ساده همراه بود. از جمله‌ی این تغییرات مهم، بازنویسی کامل کامپایلر، با خود زبان سی‌شارپ بود.

عصر چهارم: رضایت طرفداران کد تمیز و ساده
C# 7.0  , C# 7.1 , C# 7.2, C# 7.3
شروع تغییرات کوچک، در ورژن ۶ سی‌شارپ بود؛ ولی از ورژن ۷ به بعد، مایکروسافت تمرکز خیلی بیشتری را بر روی این کار گذاشت و تغییراتش همگی دارای یک هدف مهم بودند. آسان و تمیز بودن کدها؛ امکاناتی از قبلی tuple,out,ref و ... از جمله این تغییرات بودند.

عصر پنجم: دنیای Cross-Platform، خداحافظی با NullReferenceException و تلاش برای شبیه شدن به زبان‌های اسکریپت نویسی
سال‌ها برنامه نویس‌ها با خطای NullReferenceException دست و پنجه نرم میکردند، ولی حالا با استفاده‌ی درست از قابلیت Nullable reference type‌ها میشد تا حد قابل قبولی جلوی این اتفاق را گرفت. در ادامه تغییرات به سمتی می‌رفت که زبان سی‌شارپ را شبیه به یک زبان اسکریپت نویسی کرده بود. حالا میشد بدون تعریف کلاس و متد خاصی، دستور ساده‌ای را اجرا کرد. همچنین قابلیت‌هایی که در pattern matching به سی‌شارپ اضافه شد، باعث ساده‌تر و قابل فهم‌تر شدن سی‌شارپ میشد. 


نقشه‌ی راه تصویری پیشرفت سی‌شارپ

مطالب
چه زمانی بهتر است از Silverlight استفاده شود؟

1- نیاز به توانایی‌های موجود در برنامه‌های Desktop را دارید اما همچنین نیاز است تا آن‌ها را تحت وب نیز ارائه دهید.
یکی از دلایل اقبال به برنامه‌های تحت وب در سازمان‌ها عدم نیاز به نصب آن‌ها و توزیع هر چه ساده‌تر اینگونه برنامه‌ها در شبکه است. تنها کافی است چند فایل را بر روی سرور به روز رسانی کنید و پس از آن تمام کلاینت‌ها از آخرین نگارش برنامه شما بهره‌مند خواهند شد (+). توزیع برنامه‌های سیلورلایت نیز به همین منوال است. علاوه بر آن استفاده از فناورهایی مانند MEF امکان ماژولار ساختن برنامه و دریافت آخرین ماژول‌های تهیه شده (فایل‌های XAP مجزای از برنامه به صورت افزونه) را بر اساس انتخاب و سطح دسترسی کاربر نیز میسر می‌سازد.

2- نیاز است تا یک برنامه‌ی گرافیکی تمام عیار را تحت وب ارائه دهید.
توانایی‌های XAML به همراه یکی از زبان‌های دات نت جهت خلق جلوه‌های بصری، پویانمایی و گرافیکی بسیار بسیار فراتر از کتابخانه‌های جاوا اسکریپتی موجود هستند و نکته‌ی مهم آن‌ها هم این است که لازم نیست حتما یک متخصص مثلا جاوا اسکریپت باشید تا بتوانید برای مثال پویانمایی را ارائه دهید. امکان استفاده از انواع و اقسام قلم‌ها و قرار دادن آن‌ها در برنامه، امکان استفاده از گرافیک برداری و غیره را نیز لحاظ کنید.

3- برنامه‌ی شما نیاز است تا از طریق وب توزیع شود اما نیاز به سطح دسترسی بیشتری نسبت به یک برنامه‌ی وب معمولی دارد.
تمام برنامه‌های توزیع شده از طریق مرورگرها محدود به سطوح دسترسی آن‌ها نیز هستند. اما امکان نصب خارج از مرورگر برنامه‌های سیلورلایت نیز وجود دارد. در این حالت می‌توان در صورت نیاز و همچنین تائید صریح کاربر، به سطوح دسترسی بیشتری دست یافت. برای مثال دسترسی به اسکنر در یک برنامه‌ی وب متداول بی‌معنا است. اما سیلورلایت 4 در حالت اجرای در خارج از مرورگر امکان تعامل با اشیاء COM را نیز دارد.

4- برنامه‌ی وب شما نیاز است تا مدت زمان زیادی فعال باقی بماند.
یک برنامه دریافت ایمیل یا یک برنامه مونیتورینگ را در نظر بگیرید. اینگونه برنامه‌ها باید مرتبا بدون نیاز به دخالت کاربر، فعال باقی بمانند و با سرور ارتباط داشته باشند. نوشتن اینگونه برنامه‌ها با HTML و جاوا اسکریپت و فناوری‌های مشابه واقعا مشکل بوده و نیاز به دانش فنی بالایی دارند. اما این مساله و حیات یک برنامه سیلورلایت تا زمانیکه مرورگر بسته نشده است جزو خواص اولیه اینگونه برنامه‌ها است.

5- از مشکلات مدیریت حالت در برنامه‌های متداول وب به تنگ آمده‌اید.
اگر برای مثال برنامه نویس ASP.NET باشید حتما با مباحث State management آشنایی دارید (از سشن و کوکی گرفته تا ViewState (ایی که همه به نحوی قصد کوچک کردن آن‌را دارند!) و غیره). تمام این‌ها هم برای این است که بتوان تجربه‌ی کاری برنامه‌های دسکتاپ را در محیط مرورگرها شبیه سازی کرد. این مشکلات در سیلورلایت حل شده است. یک برنامه‌ی سیلورلایت State full است نه Stateless . همچنین اگر از حافظه‌ای هم استفاده می‌کند این مورد در سمت کاربر است و نه سمت سرور و نه منقضی شدن زود هنگام سشن‌ها و صدها ترفند برای مقیاس پذیری همین مساله‌ی بسیار کوچک با تعداد کاربران بالا در برنامه‌های متداول وب.
به عبارتی تصور کنید که برنامه‌ی دسکتاپ سال‌های قبل شما هم اکنون داخل مرورگر دارد اجرا می‌شود و چیزی به نام وب سرور وجود ندارد که پس از نمایش صفحه‌ی وب شما، کلیه‌ی اشیاء مرتبط با آن‌را در سمت سرور تخریب کند چون باید پاسخگوی کاربران همزمان بی‌شماری باشد و منابع سرور هم محدود است. (سیلورلایت یک فناوری سمت کاربر است. بنابراین وب سرور صرفا نقش توزیع آن‌را به عهده دارد یا حداکثر ارائه‌ی یک وب سرویس جهت تعاملات بعدی مانند کار با بانک اطلاعاتی)

6- نیاز دارید تا برنامه‌ی وب شما تحت تمام مرورگرها به یک شکل به نظر برسد و همچنین رفتار یکسانی هم داشته باشد.
هیچ وقت روزی را فراموش نمی‌کنم که حین پرداخت الکترونیکی بانک XYZ به کمک مرورگر فایرفاکس، دکمه‌ی پرداخت در مرحله‌ی آخر، کار نمی‌کرد! هر چقدر روی آن کلیک می‌کردم اتفاقی نمی‌افتاد! تراکنش برگشت خورد و همین خرید ساده با مرورگر IE به سادگی انجام شد.
با سیلورلایت این مشکلات را نخواهید داشت زیرا کار نمایش برنامه شما توسط افزونه‌ی مربوطه صورت می‌گیرد و این افزونه مستقل است از نوع مرورگر شما.

7- نیاز است برنامه‌ی وب شما در حالت آفلاین هم کار کند.
برنامه‌های سیلورلایت تنها زمانیکه نیاز به دریافت یا ثبت اطلاعاتی از سرور داشته باشند، باید آنلاین باشند. همچنین این برنامه‌ها دسترسی به مفهوم جدیدی به نام Isolated Storage دارند که در آن می‌توان اطلاعات را به ازای هر کاربر آن هم با ضریب امنیتی بالا بر روی هارد شخص ذخیره کرد و زمان آنلاین شدن برنامه آن‌ها را به سرور انتقال داد.

8- برنامه وب شما نیاز است تا با فایل‌های مالتی مدیا تعامل داشته و آن‌ها را پخش کند.
حتی تگ Video در HTML5 نیز به پای توانایی‌های مالتی مدیا در Silverlight مانند smooth streaming, multicasting, editing, video brushes نمی‌رسد. برای مثال با استفاده از video brushes می‌توان یک فایل ویدیویی در حال پخش را بر روی یک وجه یک شیء در حال پویانمایی نقاشی و نمایش داد.

9- نیاز به پشتیبانی از multi-touch در برنامه‌ی وب شما وجود دارد.
برخلاف HTML ، تعاملات multi-touch در Silverlight میسر است.

10- نیاز به ایجاد برنامه‌های بازی تحت وب دارید.
به طور قطع می‌توان بازیی‌هایی در حد Pong را با جاوا اسکریپت هم ایجاد کرد، اما اگر نیاز به تولید بازی‌هایی جدی‌تر وجود داشت برای مثال انتقال بازی Quake به محیط وب، Silverlight در این زمینه هم حرف‌های زیادی برای گفتن دارد (+).

11- نیاز به تولید برنامه‌ی دسکتاپ چند سکویی دارید.
سیلورلایت هم اکنون تحت ویندوز، MAC OS-X ، لینوکس و ... پشتیبانی می‌شود (+). همچنین برنامه‌های سیلورلایت قابلیت اجرای در خارج از مرورگر را هم دارند.
با سیلورلایت دیگر نیازی نخواهد بود تا کاربران لینوکسی ابتدا Wine را نصب کنند تا بتوانند از یک برنامه‌ی ویندوزی که انتقال پذیر نیست در لینوکس هم بتوانند استفاده کنند؛ چون پروژه‌ی مون لایت لینوکسی برای این منظور مهیا است.

12- نیاز به تولید برنامه‌های تحت وب سریع و با کارآیی بالا دارید.
فایل‌های نهایی Silverlight با توجه به ماهیت کامپایل شده‌ی آن‌ها به طور قطع از کدهای جاوا اسکریپتی سمت کلاینت که باید توسط مرورگر تفسیر و پردازش شوند (و هر کدام هم از موتور خاص خودشان استفاده می‌کنند)، سریعتر اجرا می‌شوند (+).

13- از پیچیدگی‌های پیاده سازی برنامه‌های متداول وب خسته شده‌اید.
هنوز هم با تمام پیشرفت‌های حاصل، تولید برنامه‌های وب پیشرفته مشکل است. از یک طرف ناسازگاری یک سری از مرورگرها با یک سری از قابلیت‌ها را باید در نظر داشت، تا فراگیری فریم ورک‌های Ajax و غیره تا مشکل بودن طراحی کنترل‌های جدید فراتر از آن چیزی که HTML استاندارد ارائه می‌دهد. بله، به طور قطع دانش فنی بالایی در این زمینه در طی سالیان تولید شده است، اما باز هم فراگیری و تسلط به آن‌ها زمان قابل توجهی را طلب می‌کند.
در سیلورلایت کلیه تعاملات با شبکه به صورت پیش فرض غیرهمزمان است (همان ایده‌ی اصلی Ajax) همچنین با توجه به state full بودن اینگونه برنامه‌ها، عملا برنامه نویس‌ها بدون درگیر شدن با مفاهیم اجکسی و مدیریت حالت، برنامه‌ی پیشرفته‌ی وبی را در مدت زمان کوتاهی تولید کرده‌اند و این برنامه در تمام مرورگرهایی که قابلیت بارگذاری افزونه‌ی سیلورلایت را دارند به یک شکل و کیفیت اجرا می‌شود.

14- در زمینه میزان مصرف پهنای باند ملاحظاتی ویژه‌ای وجود دارد.
یک برنامه‌ی سیلورلایت تنها یکبار باید دریافت شود. پس از آن در سمت کاربر کش خواهد شد (تا زمان به روز رسانی بعدی برنامه در سرور). همین مساله در دفعات بعدی مراجعه کاربر به سایت نقش قابل توجهی را در کاهش میزان مصرف پهنای باند (یا به قولی میزان کمتر data transfer) کلی دارد.

15- فرصت کافی برای فراگیری انبوهی از فناوری‌های مختلف را ندارید!
بله! برای ایجاد یک برنامه‌ی تحت وب که کاربر آن پس از مشاهده بگوید WOW نیاز است به HTML ، JS ، CSS ، AJAX ، یکی از فناوری‌های سمت سرور و ... مسلط بود (علاوه بر اینکه باید بدانید فلان کد JS در IE کار می‌کند اما در فایرفاکس خیر. فایرفاکس فلان قسمت CSS را پشتیبانی می‌کند اما IE خیر! و ...).
اما برای استفاده از سیلورلایت فقط کافی است به XAML و یکی از زبان‌های دات نت مانند سی شارپ یا VB.NET مسلط باشید (البته هیچ وقت از دست ASP.NET خلاص نخواهید شد! حداقل در حد راه اندازی یک وب سرویس یا مفاهیم امنیتی آن).
این مورد خصوصا برای افرادی که برنامه نویس دسکتاپ هستند اما علاقمندند تا برنامه‌ی وب نیز تولید کنند بسیار مهم است. با حداقل آموزش می‌توانند توانایی‌های خود را به وب نیز گسترش دهند. علاوه بر آن عمده‌ی دانش Silverlight شما جهت تولید برنامه‌های WPF (با توجه به اینکه Silverlight فرزند WPF محسوب می‌شود) یا Windows phone 7‌ و غیره نیز می‌تواند بکار گرفته شود.

16- نیاز به اجرای کدهای چند ریسمانی در سمت کاربر دارید.
تا این لحظه پشتیبانی رسمی از مباحث چند ریسمانی در JavaScript و استانداردهای مرتبط با آن وجود ندارد. Silverlight به اکثر امکانات Threading موجود در دات نت فریم ورک دسترسی داشته و دانش فعلی شما قابل انتقال است.


و دست آخر باید به نکته اشاره کرد که هدف از Silverlight ساخت وب سایت معمولی نیست. این نوع کارها را با همان ابزارهای متداول انجام دهید. هدف اصلی آن ساخت برنامه است (Application در مقابل Web site). مشتری‌های اصلی این نوع برنامه‌ها هم بیشتر سازمان‌ها و اینترانت‌های پر سرعت و بسته‌ی آن‌ها هستند که نه نگران حجم افزونه‌ی سیلورلایت هستند و نه مشکلی با حجم برنامه‌ی سیلورلایت شما در یک شبکه‌ی داخلی پر سرعت دارند.

مطالب
امن سازی درخواست‌های ای‌جکسی برنامه‌های ASP.NET MVC 5.x در مقابل حملات CSRF

طی مقاله چک لیست تولید برنامه Asp.net mvc و بررسی امنیتی ای‌جکس هنگام استفاده در مورد چک لیست امنیتی سایت سرفصل‌های مهم عنوان و بررسی شده است که یکی از موارد، مقاوم ساختن وب اپلیکشن در برابر حملات CSRF می‌باشد. اینگونه حملات بر پایه این استراتژی شکل می‌گیرند که با ارسال درخواستی به نیابت از سمت سیستم/مرورگر کاربر تایید هویت شده، سایت مقصد را مجبور به انجام عملی کند. برای مثال اگر شما در سایت a.com یک کاربر تایید شده باشید و هم اکنون در سایت فوق نیز لاگین باشید، مهاجم با ارسال یک برنامه/صفحه یا موارد مشابه و در قالب src یک عکس یا با ترغیب شما با کلیک بر روی یک لینک با href آلوده یا موارد مشابه، از سمت مرورگر شما درخواستی را به سمت سایت a.com ارسال می‌کند .

این درخواست ممکن است شامل حذف اطلاعات، تغییر مشخصات، پرداخت هزینه یا موارد مشابه باشد. جهت مقابله با این حمله، یکی از موارد مهم، استفاده همیشگی از Html.AntiForgeryToken() در تمامی فرم‌های ورود اطلاعات است. همچنین استفاده همیشگی از متد Post و بررسی تایید مبدا درخواست‌های ای‌جکسی، بررسی http referrer ، محدود کردن طول عمر کوکی، استفاده از کپچهای قوی مانند کپچای گوگل می‌تواند تا حد زیادی وب اپلیکیشن را در مورد اینگونه حملات، مصون کند.

در این بین یکی از موارد دیگر، اضافه کردن AntiForgeryToken به درخواست‌های ا‌ی‌جکسی سایت می‌باشد. جهت حصول این منظور، راه‌های مختلفی موجود است. یکی از راه حل‌ها استفاده از یک هلپر جهت تولید توکن مورد نظر است.

ساختار هلپر مورد نظر به شرح زیر است :

public static class AntiForgeryToken
{
  public static MvcHtmlString AntiForgeryTokenForAjaxPost(this HtmlHelper helper)
  {
    var antiForgeryInputTag = helper.AntiForgeryToken().ToString();
    // Above gets the following: <input name="__RequestVerificationToken" type="hidden" value="some value" />
    var removedStart = antiForgeryInputTag.Replace(@"<input name=""__RequestVerificationToken"" type=""hidden"" value=""", "");
    var tokenValue = removedStart.Replace(@""" />", "");
    if (antiForgeryInputTag == removedStart || removedStart == tokenValue)
       throw new InvalidOperationException("Oops! The Html.AntiForgeryToken() method seems to return something I did not expect.");
    return new MvcHtmlString($@"{"__RequestVerificationToken"}:""{tokenValue}""");
  }
}
کار آن حذف فیلد مخفی این توکن و درج آن به صورت یک شیء جاوا اسکریپتی است. 

در مرحله بعد طبق الگوی زیر، درخواست ا‌ی‌جکسی به همراه توکن تولید شده و به کنترلر ارسال خواهد شد:
function AddToCart(pid) {
   $.ajax({
     url: '@Url.Action("AddToBasket","Shop")',
     data: { 'pid': pid,@Html.AntiForgeryTokenForAjaxPost()  },
     type: 'post',
     success:function(e) {
       //do something
     }
   });
}

در مرحله آخر، باید کنترلر مورد نظر شامل ویژگی‌های [HttpPost] [ValidateAntiForgeryToken]  باشد تا صحت توکن تولیدی را بررسی کند و در صورت نامعتبر بودن، از اجرای دستورات جلوگیری گردد.
نظرات مطالب
Globalization در ASP.NET MVC - قسمت ششم
برای طراحی یک سامانه مدیرت محتوا با کلی ماژول فکر می‌کنم حرفم منطقی باشه مهندس، در ضمن همونجوری که مهندس یوسف نژاد فرمودن اطلاعات در بازیابی اولیه کش میشه و تا ری ستارت شدن سایت در حافظه می‌مونه، فکر می‌کنم چندان تاثیری بروی کارایی داشته باشه با توجه به فرضیات، فرض کن من 10000 عنوان دارم، 30 تا زبان دارم در این صورت توی یک جدول زبان انگلیسی (en-کالچر انگلیسی) 10000 بار تکرار میشه علاوه بر اون عنوان مثلا "نام کاربری" به ازای 30 زبان 30 بار تکرار میشه زیادم حرف من غیر منظقی نیست و الا حرف شما درسته بله join سرعت پایین میاره اما ما که قرار نیست زیادی دسترسی به این جداول داشته باشیم.
"پس از اولین درخواست برای هر منبع، نمونه تولیدشده از پرووایدر مربوطه در حافظه سرور کش خواهد شد." سخن مهندس یوسف نژاد
مطالب
ASP.NET Web API - قسمت پنجم
مدیریت کدهای وضعیت در Web API
تمامی پاسخ‌های دریافتی از Web API توسط Client، باید در قالب کدهای وضعیت HTTP باشند. دو کلاس جدید با نام‌های HttpResponseMessage و HttpResponseException همراه با ASP.NET MVC 4 معرفی شده اند که ارسال کدهای وضعیت پردازش درخواست به Client را آسان می‌سازند. به عنوان مثال، ارسال وضعیت برای چهار عمل اصلی بازیابی، ایجاد، آپدیت و حذف رکورد را بررسی می‌کنیم.

بازیابی رکورد
بر اساس مستندات پروتوکل HTTP، در صورتی که منبع درخواستی Client پیدا نشد، باید کد وضعیت 404 برگشت داده شود. این حالت را در متد ذیل پیاده سازی کرده ایم.
public Product GetProduct(int id)
{
    Product item = repository.Get(id);
    if (item == null)
    {
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)); 
    }
    return item;
}
در صورتی که رکوردی با مشخصه‌ی درخواستی پیدا نشد، با استفاده از کلاس HttpResponseException، خطایی به Client ارسال خواهد شد. پارامتر سازنده‌ی این کلاس، شی ای از نوع کلاس HttpResponseMessage است. سازنده‌ی کلاس HttpResponseMessage، مقداری از یک enum با نام HttpStatusCode را می‌پذیرد. مقدار NotFound، نشان از خطای 404 است و زمانی به کار می‌رود که منبع درخواستی وجود نداشته باشد. اگر محصول درخواست شده یافت شد، در قالب JSON برگشت داده می‌شود. در شکل ذیل، پاسخ دریافتی در زمان درخواست محصولی که وجود ندارد را ملاحظه می‌کنید.

ایجاد رکورد
برای ایجاد رکورد، Client درخواستی از نوع POST را همراه با داده‌های رکورد در بدنه‌ی درخواست به Server ارسال می‌کند. در ذیل، پیاده سازی ساده ای از این حالت را مشاهده می‌کنید.
public Product PostProduct(Product item)
{
    item = repository.Add(item);
    return item;
}
 این پیاده سازی کار می‌کند اما کمبودهایی دارد:
  • کد وضعیت پردازش درخواست: به طور پیش فرض، Web API، کد 200 را در پاسخ ارسال می‌کند، اما بر اساس مستندات پروتوکل HTTP، زمانی که یک درخواست از نوع POST منجر به تولید منبعی می-شود، Server باید کد وضعیت 201 را به Client برگشت بدهد.
  • آدرس منبع جدید ایجاد شده: بر اساس مستندات پروتوکل HTTP، زمانی که منبعی بر روی Server ایجاد می‌شود، باید آدرس منبع جدید ایجاد شده از طریق هدر Location به Client ارسال شود.
با توجه به این توضیحات، متد قبل به صورت ذیل در خواهد آمد.
public HttpResponseMessage PostProduct(Product item)
{
    item = repository.Add(item);
    var response = Request.CreateResponse(HttpStatusCode.Created, item);

    string uri = Url.Link("DefaultApi", new { id = item.Id });
    response.Headers.Location = new Uri(uri);
    return response;
}
همان طور که ملاحظه می‌کنید، خروجی متد از نوع کلاس HttpResponseMessage است، چون با استفاده از این نوع می‌توانیم جزئیات مورد نیاز را در مورد نتیجه‌ی پردازش درخواست به مرورگر ارسال کنیم. همچنین، داده‌های رکورد جدید نیز در بدنه‌ی پاسخ، با یک فرمت مناسب مانند XML یا JSON برگشت داده می‌شوند. با استفاده از متد CreateResponse کلاس Request و پاس دادن کد وضعیت و شی ای که قصد داریم به Client ارسال شود به این متد، شی ای از نوع کلاس HttpResponseMessage ایجاد می‌کنیم. آدرس منبع جدید نیز با استفاده از response.Headers.Location مشخص شده است. نمونه ای از پاسخ دریافت شده در سمت Client به صورت ذیل است.


آپدیت رکورد
آپدیت با استفاده از درخواست‌های از نوع PUT انجام می‌گیرد. یک مثال ساده در این مورد.

public void PutProduct(int id, Product product)
{
    product.Id = id;
    if (!repository.Update(product))
    {
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    }
}
نام متد با عبارت Put آغاز شده است. بنابراین توسط Web API برای پردازش درخواست‌های از نوع PUT در نظر گرفته می‌شود. متد قبل، دو پارامتر ورودی دارد. id برای مشخصه‌ی محصول، و محصول آپدیت شده که در پارامتر دوم قرار می‌گیرد. مقدار پارامتر id از آدرس دریافت می‌شود و مقدار پارامتر product از بدنه‌ی درخواست. به طور پیش فرض، Web API، مقدار داده هایی با نوع ساده مانند int، string و bool را از طریق route، و مقدار نوع‌های پیچیده‌تر مانند داده‌های یک کلاس را از بدنه‌ی درخواست می‌خواند.

حذف یک رکورد
حذف یک رکورد، با استفاده از درخواست‌های از نوع DELETE انجام می‌گیرد. یک مثال ساده در این مورد.
public HttpResponseMessage DeleteProduct(int id)
{
    repository.Remove(id);
    return new HttpResponseMessage(HttpStatusCode.NoContent);
}
بر اساس مستندات پروتکل HTTP، اگر منبعی که Client قصد حذف آن را دارد از پیش حذف شده است، نباید خطایی به وی گزارش شود. معمولاً در متدهایی که وظیفه‌ی حذف منبع را بر عهده دارند، کد 204 مبنی بر پردازش کامل درخواست و پاسخ خالی برگشت داده می‌شود. این کد با استفاد از مقدار NoContent برای HttpStatusCode مشخص می‌شود.

فراخوانی متدها و مدیریت کدهای وضعیت HTTP در سمت Client
حال ببینیم چگونه می‌توان از متدهای قبل در سمت Client استفاده و خطاهای احتمالی آنها را مدیریت کرد.
بهتر است مثال را برای حالتی که در آن رکوردی آپدیت می‌شود بررسی کنیم. کدهای مورد نیاز برای فراخوانی متد PutProduct در سمت Client به صورت ذیل است.
var id = $("#myTextBox").val();

$.ajax({
  url: "/api/Test/" + id,
   type: 'PUT',
   data: { Id: "1", Name: "Tomato Soup", Category: "Groceries", Price: "1.39M" },
   cache: false,
   statusCode: {
       200: function (data) {
           alert("آپدیت انجام شد");
        },
       404:
            function () {
                alert("خطا در آپدیت");
            }
      }
});
از متدهای get، getJson یا post در jQuery نمی‌توان برای عمل آپدیت استفاده نمود، چون Web API انتظار دارد تا نام فعل درخواستی، PUT باشد. اما با استفاده از متد ajax و ذکر نام فعل در پارامتر type آن می‌توان نوع درخواست را PUT تعریف کرد. خط 5 بدین منظور است. از طریق خصیصه‌ی statusCode نیز می‌توان کدهای وضعیت مختلف HTTP را بررسی کرد. دو کد 200 و 404 که به ترتیب نشان از موفقیت و عدم موفقیت در آپدیت رکورد هستند تعریف شده و پیغام مناسب به کاربر نمایش داده می‌شود.
در حالتی که آپدیت با موفقیت همراه باشد، بدنه‌ی پاسخ به شکل ذیل است.


  و در صورتی که خطایی رخ دهد، بدنه‌ی پاسخ دریافتی به صورت ذیل خواهد بود.


مطالب
مقایسه پروژه های Web Site و Web Application در Visual Studio
 در ویژوال استودیو می‌توانید پروژه‌ی Web Application و یا Web Site ایجاد نمایید. شما Web Application را با گزینه‌ی New Project ایجاد و با Open Project باز می‌کنید؛ ولی Web Site را با گزینه‌ی New Web Site ایجاد و با Open Web Site باز می‌نمایید. قبل از ساخت یک پروژه‌ی جدید وب لازم است از تفاوت‌های این دو نوع، آگاهی کسب کرده و در انتخاب نوع پروژه دقت نمایید؛ چرا که تغییر و تبدیل یک نوع به نوع دیگر، علاوه بر سختی، موجب اتلاف زمان شده و پروژه را مستعد خطا خواهد کرد.

نکته:
برای ایجاد یک پروژه‌ی جدید مایکروسافت Web Application را به شما پیشنهاد می‌دهد. هرچند در این مبحث، مطالبی را مبنی بر فواید Web Site معرفی خواهد کرد، ولی اکثر توسعه دهندگان وب که Web Site را برگزیده اند سرانجام مضراتی از آن را می‌یابند که سنگینی آن بیشتر از فوایدش است. برای مثال تمامی خصیصه‌های (feature فیچر) ASP.net لزومآ برای وب سایت در دسترس نخواهند بود؛ مثلآ از ویژوال استودیوی 2012 به بعد، ابزاری برای تولید پروژه‌های وب وجود دارد که فقط برای Web Application در اختیار خواهد بود (برای کسب اطلاعات بیشتر می‌توانید مطلب Creating an ASP.net Web Project in Visual Studio  را مطالعه نمایید). 

سناریو :

سناریویی که مبنی برا انتخاب Web Application می‌باشد به شرح زیر است:
· شما نیاز به استفاده از Edit And Continue در دیباگر ویژوال استودیو دارید.
· تمامی کدها، فایل‌ها و کلاس‌هایی که با صفحات ASP.net مرتبط هستند، برای تست بصورت واحد و یکپارچه در نظر گرفته می‌شوند.
· شما برای کلاس‌هایی که وابسته به صفحات هستند و همچنین برای کنترل‌ها و کلاس‌های منحصر آن باید ارجاع داشته باشید.
· وابستگی در حالتی که چندین پروژه‌ی مرتبط به هم را دارید توسط شما مشخص می‌شود.
· برای کل سایت در هنگام کامپایل فقط یک اسمبلی ساخته می‌شود.
· کنترل نام اسمبلی‌ها و همچنین شمارهی ورژن ایجاد شده‌ی برای پروژه در دست شماست.
· برای کامپایل پروژه می‌توانید MSBuild و یا Team Build را انتخاب کنید؛ برای مثال می‌توانید مراحل Prebuild یا Postbuild را مشخص کنید.
· نیازی به قرار دادن سورس برنامه روی سرور نیست.

سناریویی که مبنی برا انتخاب Web Site می‌باشد به شرح زیر است:
· یک پروژه در بر دارنده‌ی  کدهای #C و هم کدهای Visual Basic می‌باشد ( درحالیکه بصورت پیشفرض در Web Application فایل پروژه بر مبنای زبان برنامه‌ی شما کامپایل می‌شود، هرچند می‌توان این حالت پیشفرض را تغییر داد؛ ولی این امر می‌تواند اندکی مشکل باشد).
· شما می‌توانید سایت ایجاد شده را بصورت Real Time توسط FTP  باز نموده و آپدیت نمایید.
· برای توزیع (deploy) پروژه مجبور به کامپایل صریح آن نیستید.
· اگر پروژه را کامپایل نمایید کامپایلر به ازای هر صفحه و یا هر پوشه، یک فایل اسمبلی جداگانه خواهد ساخت.
· برای تغییر یک فایل به تنهایی می‌توانید فقط آنرا تغییر داده و بر روی سرور قرار دهید.
· حتی بعد از کامپایل هم می‌توانید صفحات ASP.net  را بدون نیاز به کامپایل دوباره‌ی کل سایت تغییر داده و جایگزین نمایید.
· سورس کامل پروژه برای اجرا باید روی سرور قرار گیرد.

تفاوت‌ها در یک نگاه:

زمینه 
  پروژه‌های Web Application     پروژه‌های Web Site 
  ساختار فایل پروژه    فایل برنامه (.csproj / vbproj) دربردارنده اطلاعاتی از جمله لیست فایل‌ها و رفرنس‌ها پروژه به پروژه دیگر خواهد بود.    هیچ فایل برنامه ای وجود ندارد و تمامی فایل هایی که داخل پوشه می‌باشند جزو فایل‌های سایت شناخته می‌شوند. 
  کامپایل  · شما پروژه را در سیستم خود کامپایل می‌کنید.
· بصورت پیشفرض کامپایل کد‌ها در یک اسمبلی قرار می‌گیرد. 
  · سورس کدها بصورت اتوماتیک در سرور توسط Asp.net  با اولین درخواست کامپایل میشوند.
(البته شما می‌توانید کامپایل را در سیستم خود نیز انجام دهید)
· بصورت پیشفرض کامپایل برای هر کلاس یک اسمبلی جدا می‌سازد. 
فضا‌های نام  Namespace‌ها بصورت صریح در صفحات و کلاس‌ها و کنترل‌ها افزوده می‌شود.  هیچ namespace ای بصورت پیشفرض اضافه نمی‌شود (شما می‌توانید بصورت دستی آنها را اضافه کنید) 
توزیع
اسمبلی تولید شده در مرحله کامپایل را روی سرور قرار می‌دهید
اکثر مراحل کامپایل توسط ابزارهای ارائه شده ویژوال استودیو انجام می‌شود. 
کل سورس پروژه روی سرور قرار میگیرد.
اکثر مراحل کامپایل توسط ابزارهای ارائه شده ویژوال استودیو انجام می‌شود. 

ساختار فایل پروژه:
پروژه‌های Web Application از فایل پروژه ویژوال استودیو ( .csproj / .vbproj ) برای نگهداری اطلاعات پروژه استفاده می‌کنند. با این امکان می‌توان فایل‌هایی را که در پروژه دخیل هستند و یا باید کامپایل شوند، به تفکیک مشخص کرد.
در مورد Web Site تمامی فایل‌هایی که در داخل پوشه‌ی برنامه قرار دارند، به صورت پیش فرض جزیی از برنامه تلقی شده و کامپایل خواهند شد و برای اینکه فایلی را بخواهید مستثنا کنید یا باید آنرا حذف کنید و یا پسوند آنرا به نامی که توسط سرور IIS قابل شناسایی نیست تغییر دهید.

فایده‌ی فایل پروژه یعنی همان ( .csproj / .vbproj ) در Web Application :
می‌توان فایلی را به طور موقت از برنامه حذف کرد، بدون نگرانی از آنکه فایل بصورت کلی حذف شود. چرا که فایل در ساختار برنامه باقیست. برای مثال اگر صفحه‌ای برای توزیع آماده نیست، می‌توانید به راحتی آن‌را از برنامه خارج کنید ( Exclude ) و برنامه را کامپایل نمایید و بعد از اینکه این صفحه هم آماده شد، دوباره آن را وارد پروژه نمایید ( include ) که اهمیت این امر در مواردی که از برنامه‌های کنترل سورس استفاده می‌کنید، دوچندان می‌شود.

فایده‌ی عدم استفاده از فایل پروژه‌ی برنامه در Web Site :
شما مجبور به کنترل و شخصی سازی ساختار فایل برنامه در ویژوال استودیو نیستید و به راحتی هر فایل یا صفحه‌ای را که می‌خواهید، با کپی کردن به پوشه و یا حذف کردن از آن توسط فایل اکسپلورر انجام می‌دهید.

کامپایل:
برای برنامه‌های Web Application شما بصورت معمول پروژه را Build می‌نمایید و تمامی کد‌های صفحات و همچنین کلاس‌ها به صورت یک فایل اسمبلی در پوشه‌ی bin ذخیره می‌گردد.
برای Web Site شما مجبور به کامپایل دستی پروژه نیستید و می‌توانید از Batch-Compile استفاده کنید و همچنین به ازای هر صفحه و کلاسریال شما یک فایل اسمبلی خواهید داشت.

مزایای کامپایل در Web Application :
· می‌توانید از MSBuild استفاده کنید.
· می‌توانید خصیصه‌های اسمبلی، از جمله نام و ورژن را به راحتی مدیریت نمایید.
· کامپایل قبل از توزیع برنامه این مزیت را دارد که کاربران مجبور نیستند منتظر کامپایل برنامه در سرور باشند.
· مدیریت دقیقی بر روی فایل‌ها و ساختار برنامه و همچنین کلاس‌ها و ارجاعات خواهید داشت.

مزایای کامپایل در Web Site  :
· می‌توانید هر صفحه‌ای را که نیاز دارید بدون در نظر گرفتن آماده شدن دیگر صفحات تست و اجرا نمایید.
· آپدیت و جایگزینی فایل‌ها به راحتی صورت می‌گیرد؛ چرا که اسمبلی تمام فایل‌ها بصورت منحصر همان صفحه ایجاد خواهد شد.
· ایجاد شدن چند اسمبلی می‌تواند در برخی پروژه‌ها به نفع برنامه بوده و performance  را بالا ببرد. برای مثال در حالتیکه یک سایت با صفحات زیاد دارید و برخی صفحات به نسبت دیگر صفحات خیلی کمتر درخواست می‌شوند.

نکته:
هیچ فرقی بین Web Application ,  و web Site از نظر performance  وجود ندارد مگر درحالت ذکر شده در بالا و در سایت‌های خیلی بزرگ.

توزیع : ( Deployment )
در web Site کل فایل‌های پروژه را بر روی سرور قرار می‌دهید؛ درحالی که در Web Application  فایل‌های برنامه بصورت اسمبلی‌ها ( .dll ) روی سرور قرار می‌گیرند. همین امر می‌تواند در برخی حالت‌ها مثلآ زمانی که از هاست share شده استفاده می‌کنید، خیال شما را از بابت سورس برنامه مطمئن سازد.
برای Web Site نیز این مزیت وجود دارد که برای انجام تغییرات کوچک مجبور به کامپایل و آپلود دوباره‌ی کل پروژه نیستید.


ماخذ

 
نظرات اشتراک‌ها
همکاری مایکروسافت با تیم Mono در مورد portable class libraries
مدتی است بدنبال برنامه نویسی اندروید هستم و بین انتخاب زبان سی شارپ و جاوا مردد هستم . کدام گزینه‌ی بهتری برای کار هست استفاده از جاوا یا سی شارپ ؟ آیا ممکنه بلایی که سر سیلورلایت اومد سر برنامه نویسان اندروید (سی شارپ) هم بیاد ؟ اگر بخواهیم آینده نگری کنیم کار رو با کدوم پیش ببریم و ابزارها و امکانات کدوم بهتر هست ؟

نظرات مطالب
بررسی وجود نام کاربر با استفاده از jQuery Ajax در ASP.Net
سلام
بله. برنامه reflector معروف که مد نظر هست. اسمبلی برنامه فوق را با آن باز کردم و زبان انتخابی هم VB . حاصل به صورت زیر نمایش داده شد:
Public Shared Function IsUserAvailable

یک سری کار سورس باز دیدم در CodePlex در مورد jQuery Ajax که تلاش‌هایی برای ساده‌تر کردنش کردند. بد نیست برای تکمیل کار یک سری هم به آن‌ها هم بزنید. برای ایده گرفتن خوب است.
نظرات مطالب
طبقه بندی Bad Code Smell ها
اگر if ، switch  ربطی به یک زبان شیءگرا نداشتند، اصلا در آن قرار نمی‌گرفتند. اگر میزان پیچیدگی یک برنامه افزایش پیدا کند، قطعا نگهداری آن مشکل‌تر خواهد شد. درک آن توسط سایر اعضایی که آن کد را ننوشته‌اند مشکل‌تر خواهد شد. همچنین نیاز به مستندات بیشتری خواهد داشت.
استفاده از switch یعنی طراحی دقیق برنامه. یعنی حالت‌های مختلف مورد استفاده مشخص هستند و تفکری در پشت طراحی یک برنامه وجود داشته. اما زمانی هست که می‌خواهید به استفاده کننده‌ی از یک API امکان مانور بیشتری را بدهید تا بتواند قطعاتی را به برنامه متصل کند. در این حالت بهتر است از الگوی استراتژی بجای استفاده از روش‌هایی که تقریبا در هیچ پروژه‌ی مطرحی استفاده نمی‌شود، کمک گرفت. بنابراین باید دقت داشت که آیا ما درحال طراحی یک قطعه کد برای عموم هستیم یا یک برنامه‌ی مشخص با طراحی کاملا دقیق.