پروژه‌ها
TaskoMask : سیستم مدیریت تسک سورس باز مبتنی بر NET 6, Microservices, DDD
توضیح
پروژه‌ی سورس باز TaskoMask یک سیستم مدیریت تسک رایگان می‌باشد که سورس آن را می‌توانید از طریق این آدرس در گیت هاب مشاهده کنید. همچنین این پروژه از طریق آدرس taskomask.ir نیز در دسترس میباشد.
برای استفاده مفیدتر از این پروژه، داکیومنت‌های مورد نیاز شامل بخش دامین، معماری، وب سرویس و ... ایجاد شده اند که از طریق ریپازیتوری این پروژه بر روی گیت هاب در دسترس هستند.


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


ویژگی ها
در اینجا برخی ویژگی‌های مهم این پروژه را بررسی میکنیم ولی برای اطلاع از لیست دقیق ویژگی‌ها و امکانات این پروژه و نیز دسترسی به داکیومنت‌ها و بورد‌های آن، بهتر است به ریپازیتوری آن در گیت هاب مراجعه کنید.
NET 6.
#C
Blazor
 ASP.NET Web API
ASP.NET MVC
MongoDB
Redis
MediatR
Microservices
 DDD
CQRS
Event Sourcing
Notification
Repository
Onion Architecture 
 Acceptance Testing
Integration Testing
Unit Testing
UI Testing
E2E Testing


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


درخواست حمایت 
اگر این پروژه به هر نحوی برای شما سودمند بود با دادن یک ستاره ⭐ در گیت هاب ما را حمایت کنید.


تصاویر پروژه

نظرات نظرسنجی‌ها
در محیط برنامه نویسی از دارک مود استفاده می کنید یا لایت مود؟
درود به همه دوستان و با احترام به همه نظرات
بنده تقریبا از زمانی که dark mode در دسترس قرار گرفت از این حالت تیره استفاده میکنم ، خوب قبلا از محیط روشن light mode استفاده میکردم تجربیاتی که داشتم رو ذکر میکنم :
  1. به دلیل کار بیش از 10 ساعت روزانه ، با توجه به اینکه مشکل بینایی نداشتم ولی حالت روشن باعث عصبی بودن و بیخوابی مزمن شده بود با تغییر محیط به حالت تیره تاثیر بسیار زیادی در کیفیت خواب داشتم بصورتی که این موضوع کاملا محسوس بود.
  2. از طرفی کار با 2 یا 3 مانیتور با حالت روشن ، نیاز به دقت بیشتری دارد و خستگی زیادی رو به چشم تحمیل میکند و مدت زمان کمتری با دقت بالا میتونستم کار کنم و تمرکزم به دلیل صفحه سفید کمتر بود.
  3. اگر محیط نور مناسب و ملایمی داشته باشد و از پشت سر باشد حالت روشن خستگی کمتری خواهد داشت و چشم رو کمتر اذیت میکنه ولی در حالت تیره خستگی چشم خیلی کمتر خواهد بود و تداخل رنگی کمتری داریم.
  4. برای برنامه نویسی بلند مدت ، حالت تیره و برای طراحی گرافیک و کار با تصاویر حالت روشن (به دلیل وضوح مناسب ) بیشتر توصیه میکنم .
مشاغل مشابه برنامه نویسی و کار با کامپیوتر به دلیل عدم تحرک کافی بدن و پشت میز نشینی آسیبهای زیادی را وارد میکند اما در هر صورت به نظرم هر کسی قبل از انتخاب محیط کاری خود باید با یک چشم پزشک آشنا به تکنولوژی و شغل مورد نظر ، مشاوره کند تا بتواند از محیط شغلی خودش کمتر آسیب ببیند.

دوره‌ها
طراحی یک فریم ورک برای کار با WPF و EF Code First توسط الگوی MVVM
در این دوره، قالب تهیه یک پروژه جدید WPF مبتنی بر EF Code first را دریافت خواهید کرد که دارای این مشخصات است:

1- اعتبارسنجی یکپارچه با EF Code first

2- دارای سیستم راهبری (Navigation) بین صفحات با قابلیت تزریق خودکار وابستگی‌ها توسط کتابخانه StructureMap
3- به همراه مباحثی مانند تعریف کاربران، تعریف سطوح دسترسی و همچنین راهبری بین صفحات برنامه با درنظر گرفتن این مسایل به کمک تنها افزودن یک ویژگی به نام PageAuthorization به ابتدای تعریف کلاس یک صفحه



4- دارای سیستم خودکار پیغام دهی به کاربر در صورتیکه قصد حرکت به صفحه‌ای دیگر را داشته باشد؛ اما تغییرات صفحه جاری ذخیره نشده‌اند.


5- قالب پروژه جدید تدارک دیده شده، به صورت خودکار لایه بندی‌های برنامه را تدارک خواهد دید (شامل DataLayer، DomainClasses، ServiceLayer و غیره)
6- به همراه سیستم DbContext یکپارچه با مباحثی مانند یکسان سازی ی و ک در برنامه به صورت خودکار و نمایش مشکلات اعتبارسنجی داده‌ها به کاربر بدون نیازی به کد نویسی اضافه.
7- این قالب پروژه با کتابخانه‌های زیر یکپارچه است:
Entity Framework Code First
Fody (جهت اعمال مسایل AOP برای کاهش تدارک کدهای INotifyPropertyChanged در برنامه)
MahApps.Metro (برای نمایش قالب مترو سازگار با دات نت 4)
Microsoft.SqlServer.Compact.4 (بانک اطلاعاتی پیش فرض برنامه دسکتاپ تدارک دیده شده)
MvvmLight (پایه مباحث MVVM بکارگرفته شده در برنامه)
StructureMap (جهت پیاده سازی مباحث تزریق وابستگی‌ها در برنامه)
نظرات اشتراک‌ها
بررسی آینده‌ی Blazor در دات نت 8
خلاصه‌ی این مفهوم «United» به این صورت است:
- blazor server از لحاظ عدم نیاز به دریافت چند صد فایل مرتبط با web assembly و همراه بودن با رندر سمت سرور، در ابتدای کار نمایش برنامه، سریعتر نمایش داده می‌شود و این نمایش اولیه تقریبا آنی است.
- Blazor WASM چون به طور کامل در مرورگر اجرا می‌شود و در جهت رندر صفحات نیازی به رفت و برگشت به سرور ندارد، سرعت اجرایی فوق العاده‌ای دارد؛ اما به همراه بارگذاری تعداد زیادی فایل در ابتدای کار نمایش آن است که ... کمی طول می‌کشد که البته می‌توان با استفاده از فعال سازی per-rendering کمی آن‌را سریعتر کرد که نیاز به تنظیمات قابل توجهی دارد که شاید همه از آن استفاده نکنند.
اکنون قرار است در دات نت 8 بتوان به صورت خودکار ابتدا یک صفحه را با استفاده از server side rendering موجود در Blazor Server، سریع نمایش داد (بدون نیاز به دریافت فایل‌های WASM و منتظر شدن برای آن‌ها) و بعد در همان حال در پشت صحنه و به صورت خودکار، همین برنامه با قالب Blazor web assembly هم دریافت می‌شود تا در بار بعدی که این صفحه قرار است نمایش داده شود، بتوان به حداکثر سرعت کار با Blazor، با استفاده از اجرای کامل آن در مرورگر توسط web assembly رسید. یعنی ترکیب همزمان blazor server و blazor web assembly، بدون نیاز به تنظیمات خاصی در جهت از پیش رندر کردن صفحات و یا منتظر ماندن اولیه و نمایش یک صفحه‌ی خالی در جهت بارگذاری تمام فایل‌های یک برنامه‌ی web assembly؛ هر دو با هم به صورت یکپارچه و یک‌دست. حتی می‌توان مشخص کرد که صفحه‌ای فقط بر اساس blazor server اجرا شود و صفحه‌ای دیگر فقط قسمتی از آن از blazor wasm استفاده کند.
اشتراک‌ها
معرفی فریمورک متن باز رابط کاربری HandyControl برای WPF

یک سالی میشود که روی یک فریمورک رابط کاربری بصورت متن باز به اسم HandyControl مشارکت دارم، این فریمورک در درجه اول مخصوص برنامه نویس‌های چین طراحی شده بود اما با بازخوردهایی که دریافت کرد، جامعه انگلیسی زبان را هم پشتیبانی میکند. بدلیل اینکه هدف این فریمورک ارائه کنترل‌های ساده و بدور از پیچیدگی هست، Nabian با اضافه کردن کنترل‌های پیچیده مخالف هست. به همین دلیل تصمیم گرفتم تا شاخه جدایی از این پروژه را ایجاد کنم و کنترل‌ها و ویژگی‌های مختلفی که سازگار با برنامه نویس‌های ایرانی باشد را اضافه کنم. درحال حاضر تقویم شمسی، ساعت_تقویم شمسی، پشتیبانی از کد ملی، حروف فارسی در نوع ورودی TextBox ،استایل‌های جدید بارگذاری، کنترل BusyIndicator، کنترل سرعت شمار (SpeedoMeter) و چندین کلاس هلپر جهت کار با رجیستری، رمزنگاری و... را به پروژه اضافه کردم.(لیست ویژگی‌های اضافه شده را میتوانید از این قسمت مشاهده کنید) (جهت مشاهده کنترل‌ها و ویژگی‌های اضافه شده در نسخه شخصی سازی شده بعد از اجرای دمو از بخش Controls بخش PersianToolkit را انتخاب کنید)

صفحات پروژه اصلی===> سورس برنامه | صفحه ناگت | صفحه مارکت پلیس مستندات چینی | مستندات انگلیسی | مستندات ویکی

 اگر پیشنهادی برای اضافه کردن کدهای کاربردی یا کنترل‌های کاربردی دارید لطفا در نظرات اعلام کنید و یا اگر خودتان توانایی آن را دارید در گیتهاب PR ارسال کنید.
 

معرفی فریمورک متن باز رابط کاربری HandyControl برای WPF
نظرات مطالب
Globalization در ASP.NET MVC
سلام مهندس یوسف نژاد (ابتدا ممنونم از پست خوب شما)
با پیروی از پست شما
ابتدا فایل‌های ریسورس در پروژه جاری فولدر App_GlobalResources گذاشتم و پروژه در صفحات aspx با قالب زیر به راحتی تغییر زبان داده میشد:

<asp:Literal ID="Literal1" Text='<%$ Resources:resource, Title %>' runat="server" />
اما بعدش فایل هارو توی یک پروژه کتابخانه ای جدید گذاشتم و Build Action فایل‌های ریسورس روی Embedded Resource  تنظیم کردم، پروژه با موفقیت اجرا شد و در سمت سرور با کد زیر راحت به مقادیر دسترسی دارم:
Literal1.Text=ResourcesManager.Resource.Title;
اما در سمت صفحات aspx با کد قبلی به شکل زیر نمایش نمیده و خطا صادر میشه:
<asp:Literal ID="Literal1"  runat="server" Text='<%$ ResourcesManager.Resource:resource, Title %>'/>

و خطای زیر صادر میشه:
 Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

Parser Error Message: The expression prefix 'ResourcesManager.Resource' was not recognized.  Please correct the prefix or register the prefix in the <expressionBuilders> section of configuration.

Source Error:
مراحل این پست روی هم دنبال کردم اما بازم نشد.
چه تنظیماتی ست نکردم ؟


مطالب
استفاده از BroadcastChannel در جاوا اسکریپت

یکی از API ‌های کاربردی و جدید در دنیای وب، BroadcastChannel است که امکان ارسال اطلاعات بین window‌ها ، Tab‌ها و iframe‌های مختلف را که در یک دامنه هستند، فراهم می‌کند.  برای مثال اگر شما در مرورگری در پنجره‌های مختلف یک سایت را باز کرده باشید، با تغییر در یکی از این پنجره‌ها، قادر خواهید بود سایر پنجر‌ها را هم مطلع کنید تا در صورت نیاز، مجددا بارگذاری شوند. 


چرا از این API استفاده کنیم؟ 

یکی از وب سایت‌های مورد علاقه‌ی خود را در مرورگر باز کنید. مثلا یوتیوب و لاگین کنید. حالا در پنجره‌ی جدیدی، همین وب سایت را مجددا باز کرده و لاگین کنید. حالا در یکی از پنجره‌ها، از یوتیوب Logout کنید. خب شما حالا در یکی از پنجره‌ها لاگین هستید و در یکی دیگر Logout کرده‌اید. حالا پنجره‌های مرورگر شما دارای دو وضعیت متفاوت هستند. Logged-in در برابر Logged-out و این گاهی باعث دردسر خواهد شد.

این وضعیت حتی میتواند باعث خطرهای امنیتی نیز بشود. تصور کنید که کاربری در یک فضای عمومی مثل یک کافی شاپ وارد سایت شما شده‌است و داشبرد مخصوص به خود را باز کرده‌است. بنا به دلایلی کاربر قصد ترک محل را کرده و طبیعتا از برنامه شما Logout خواهد کرد . در این حالت اگر این کاربر برنامه شما را در صفحات مختلف مرورگر باز کرده باشد و لاگین نیز کرده باشد، هر کسی که بعد از او قصد استفاده از این کامپیوتر را داشته باشد ،  میتواند به اطلاعات کاربر مورد نظر در آن صفحات دسترسی پیدا کند؛ چه این اطلاعات روی صفحه باشد و چه مثلا اطلاعات یک JWT token.  چون کاربر فراموش کرده در صفحات دیگر هم Logout کند.


کد نویسی BroadcastChannel API 

در نگاه اول، استفاده از این API  ممکن است سخت به نظر برسد؛ ولی در واقع خیلی راحت است. برای نمونه قطعه کد زیر را درنظر بگیرید: 

<!DOCTYPE html>
<body>
  <!-- The title will change to greet the user -->
  <h1 id="title">Hey</h1>
  <input id="name-field" placeholder="Enter Your Name"/>
</body>
<script>
var bc = new BroadcastChannel('gator_channel');
(()=>{
  const title = document.getElementById('title');
  const nameField = document.getElementById('name-field');
  const setTitle = (userName) => {
    title.innerHTML = 'Hey ' + userName;
  }
  bc.onmessage = (messageEvent) => {
    // If our broadcast message is 'update_title' then get the new title from localStorage
    if (messageEvent.data === 'update_title') {
      // localStorage is domain specific so when it changes in one window it changes in the other
      setTitle(localStorage.getItem('title'));
    }
  }

  // When the page loads check if the title is in our localStorage
  if (localStorage.getItem('title')) {
    setTitle(localStorage.getItem('title'));
  } else {
    setTitle('please tell us your name');
  }
  nameField.onchange = (e) => {
    const inputValue = e.target.value;
    // In the localStorage we set title to the user's input
    localStorage.setItem('title', inputValue);
    // Update the title on the current page
    setTitle(inputValue);
    // Tell the other pages to update the title
    bc.postMessage('update_title');
  }
})()
</script>

این کد شامل یک Input باکس و یک title است. وقتی کاربر نام خود را در Input باکس وارد می‌کند، برنامه آن را در Localstorage با کلیدی به نام userName ذخیره می‌کند و بعد title صفحه جاری را به سلام + userName تغییر می‌دهد. مثلا اگر کاربر در Input باکس، عبارت بابک را وارد کند، title صفحه به سلام بابک تغییر داده میشود.

بدون BroadcastChannel، چنانچه کاربر در پنجره‌های مختلف مرورگر، برنامه را باز کرده باشد، تغییری در Title آن صفحات داده نخواهد شد؛ مگر اینکه مجددا توسط کاربر بارگذاری شود. 

در کد فوق ما یک وهله از BroadcastChannel را به نام gator_channel ایجاد کرده‌ایم و بعد onmessage را مساوی متدی با یک آرگومان جهت دریافت پیام قرار داده‌ایم. در این متد چک شده که اگر نام پیام، مساوی update_title باشد، متغیر ذخیره شده‌ی در LocalStorage خوانده شود.

هربار که متد postMessage ، از BroadcastChannel را فراخوانی میکنیم، این متد، باعث اجرای متد onmessage در سایر پنجره‌ها می‌شود. پس اگر در پنجره‌ی جاری در Input باکس، کلمه فرهاد را بنویسیم، متد bc.postMessage('update_title') در پنجره جاری اجرا شده و باعث اجرای متد onmessage در سایر پنجره‌هایی که سایتمان در آن باز است میشود.


این API در چه حالت‌هایی کار میکند

برخلاف سایر API‌ها مثل window.postMessage، شما لازم نیست چیزی در مورد اینکه چند تا صفحه از سایتتان بر روی مرورگر جاری باز شده را بدانید. (توجه کنید که روی عبارت «مرورگر جاری» تاکید میکنم. چون اگر برنامه روی دو مرورگر مثلا Chrome و Firefox به صورت همزمان باز باشد، این API فقط روی صفحات باز مرورگر جاری فراخوانی خواهد شد و نه مرورگر دوم؛ توضیحات بیشتر در ادامه داده شده است)

BroadcastChannel فقط روی مرورگر جاری و صفحاتی از یک دامنه، اجرا خواهد شد. این به این معنا است که شما می‌توانید پیام‌هایتان را از دامنه مثلا : https://alligator.io به دامنه https://alligator.io/js/broadcast_channels ارسال کنید. تنها نکته‌ای که لازم است تا رعایت شود این است که آبجکت BroadcastChannel در هر دو صفحه، از یک نام برای channel استفاده کرده باشند:

const bc = new BroadcastChannel('alligator_channel');
bc.onmessage = (eventMessage) => {
  // do something different on each page
}


در حالتهای زیر این API کار نخواهد کرد:

هاست‌های متفاوت:

https://alligator.io 

https://www.aligator.io

پورت‌های متفاوت:

https://alligator.io 

https://alligator.io :8080

پروتکل‌های متفاوت:

https://alligator.io 

http://alligator.io 

و یا برای مثال اگر مثلا در مرورگر Chrome یکی از صفحات به صورت Incognito باز شده باشد.


سازگاری این API با مرورگرهای مختلف

با توجه به اطلاعات سایت caniuse.com، این API در 75.6% مرورگرها پشتیبانی میشود. ولی مرورگرهای Safari و Internet Explorer از این API پشتیبانی نمی‌کنند. همچنین امکان استفاده از این API توسط کتابخانه sysend.js نیز فراهم شده‌است.


چه نوع پیامهایی را می‌توانید به کمک این API ارسال کنید

  • تمامی تایپ‌ها (Boolean,Null, Undefined,Number,BigInt, String) به غیر از symbol
  • آبجکتهای Boolean و String
  • Dates
  • Regular Expressions
  • Blobs
  • Files, File Lists
  • Array Buffer, ArrayBufferViews
  • ImageBitmaps, ImageDates
  • Arrays,Objects,Maps and Sets
در صورت ارسال تایپی از نوع symbol، با خطایی در سمت ارسال کننده مواجه خواهید شد.

قطعه کد زیر، بجای string، یک object را ارسال می‌کند:

bc.onmessage = (messageEvent) => {
  const data = messageEvent.data
  // If our broadcast message is 'update_title' then get the new title from localStorage
  switch (data.type) {
    case 'update_title':
      if (data.title){
        setTitle(data.title);
      }
      else
        setTitle(localStorage.getItem('title'));
      break
    default:
      console.log('we received a message')
  }
};
// ... Skipping Code
bc.postMessage({type: 'update_title', title: inputValue});


چه کارهایی را میتوانید به کمک این API انجام دهید

چیزهای زیادی را میتوان مجسم کرد. محتمل‌ترین گزینه، به اشتراک گذاری state جاری برنامه است. برای مثال اگه از کتابخانه‌های flux یا redux برای مدیریت state برنامه استفاده می‌کنید، به کمک این API می‌توانید state جاری را در تمامی صفحات باز برنامه، بروز رسانی کنید. حتی می‌توانید به چیزی شبیه به machine state فکر کنید.

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

به کمک دستور ()bc.close در هر زمانی میتوانید channel باز شده را ببندید و مجددا بسته به وضعیت برنامه، آن را باز کنید.

مطالب
راه‌های متفاوت رندر لایه‌ها در ASP.NET MVC
در MVC لایه‌ها (Layouts) مانند Master Page‌ها در وب فرم عمل می‌کنند. این به ما کمک می‌کند تا بتوانیم از تکرار کدها پرهیز کنیم و سریعتر صفحات خودمان را گسترش دهیم. مثل Master Page‌ها، این صفحات هم (Layouts) می‌تواند شامل قالب‌های CSS مختلف، کدهای Javascript مختلف و قالب بندی‌های مختلفی باشند.
در میان View‌های یک برنامه MVC فایلی را به عنوان    _ViewStart  داریم که وظیفه‌ی آن نگهداری قالب اصلی برنامه‌ی ما است.
در این مقاله سعی شده است تا راه‌های موجود برای استفاده از این قالب‌ها را در یک برنامه MVC، بررسی کنیم.
فرض ما بر این است که می‌خواهیم لایه‌ای را که در تصویر زیر می‌بینید، مورد استفاده قرار دهیم:

روش شماره 1 : استفاده از  _ViewStart موجود در ریشه‌ی پوشه Views

با استفاده از کد زیر می‌توانیم فایل پیش فرضی را که قرار است رندر شود، تغییر دهیم:

@{
 var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
 
 string layout = "";
 if (controller == "Admin")
 {
 layout = "~/Views/Shared/_AdminLayout.cshtml";
 }
 else
 {
 layout = "~/Views/Shared/_Layout.cshtml";
 }
 
 Layout = layout;
}


روش شماره 2 : مشخص کردن لایه در Action

همچنین می‌توانیم فایل مورد نظر را در اکشن خودمان، بازنویسی (override) کنیم:

public ActionResult Index()
{
 RegisterModel model = new RegisterModel();
 //TO DO:
 return View("Index", "_AdminLayout", model);
}

روش شماره 3 : مشخص کردن لایه به ازای هر View

می‌توانیم در هر View هم لایه مربوط به آن را مشخص کنیم:

@{
 Layout = "~/Views/Shared/_AdminLayout.cshtml";
}

روش شماره 4 : اضافه کردن فایل _ViewStart به ازای هر کنترلر

همانطور که در تصویر زیر می‌بینید آخرین روش این هست که می‌توانید فایل‌های _ViewStart مختلفی را به ازای هر کنترلر، داخل پوشه View مربوطه قرار بدید تا سیستم از آن استفاده کند. 

مطالب
بارگذاری فایل‌های ایستا از پوشه‌ی Views در ASP.NET MVC
گاهی از اوقات تنها نیاز است یک View خاص و نه تمام صفحات سایت، فایل اسکریپت ویژه‌ی خود را مورد استفاده قرار دهد. در این حالت می‌توان فایل اسکریپت مورد نیاز آن‌را مطابق معمول در پوشه‌ی Scripts در کنار سایر فایل‌ها قرار داد و یا ... حتی شاید بهتر باشد این فایل اسکریپت ویژه را در همان پوشه‌ی View مورد نظر قرار داد. اگر اینکار را انجام دهیم، برنامه کار نخواهد کرد و فایل اسکریپت با خطای 404، بارگذاری نمی‌شود. علت اینجا است که در ریشه پوشه‌ی Views، فایل web.config خاصی با تنظیم ذیل قرار دارد:
  <system.webServer>
    <handlers>
      <remove name="BlockViewHandler"/>
      <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode"
           type="System.Web.HttpNotFoundHandler" />
    </handlers>
  </system.webServer>
به این ترتیب هر درخواستی که به پوشه‌ی views یک برنامه‌ی ASP.NET MVC برسد، با پیغام 404 مواجه خواهد شد.
در ادامه می‌خواهیم این تنظیم همانگونه که بوده‌است، حفظ شود (چون مسیر پردازش صفحات در MVC از کنترلر به View است و نیازی نیست تا ابتدا View خاصی بارگذاری شود) اما اجازه دهیم تا فایل‌های JavaScript از این مسیر قابل بارگذاری و استفاده شوند. برای این منظور می‌توان با ویرایش فایل Views/web.config به صورت زیر عمل کرد:
  <system.webServer>
    <handlers>
      <add name="JavaScriptHandler"
         path="*.js"
         verb="*"
         preCondition="integratedMode"
         type="System.Web.StaticFileHandler" />
      <remove name="BlockViewHandler"/>
      <add name="BlockViewHandler" 
           path="*" 
           verb="*" 
           preCondition="integratedMode"
           type="System.Web.HttpNotFoundHandler" />
    </handlers>
  </system.webServer>
در اینجا امکان قرار دادن فایل‌های اسکریپت یک پوشه‌ی خاص تحت ریشه‌ی Views و بارگذاری معمولی آن میسر شود؛ بدون اینکه امکان دسترسی به فایل‌های cshtml یا سایر فایل‌های دیگر مانند قبل وجود داشته باشد.


در ادامه برای مسیر دهی این فایل اضافه شده باید به نحو ذیل عمل کرد:
 <script type="text/javascript" src="~/Views/Home/Test.js"></script>
مطالب
قابلیت های کاربردی ASP.NET WebFroms - قسمت اول
قابلیت CompositeScript 
پس از گذشت مدتی که از توسعه پروژه مورد نظرتان می‌گذرد احتمالاً فایل‌های javascript زیادی در پروژه شما استفاده می‌شود که هم مدیریت و هم بار سنگینی بر سرعت بارگذاری اولیه سایت شما به دلیل زمان بارگذاری فایل‌های javascript خواهد گذاشت. در ASP.NET چندین روش برای مدیریت فایل‌های javascript , css  وجود دارد.
ساده‌ترین روش استفاده از امکانات خود ASP.Net  است. با قابلیت CompositeScript براحتی می‌توانید فایل‌های javascript خود را با هم ادغام و در یک فایل ScriptResource.axd برای Client ارسال نمایید. برای این کار کافیست از تگ جدید CompositeScript در کنترل ScriptManager استفاده نمایید. در کد زیر این قابلیت نمایش داده شده است:
 <asp:ScriptManager ID="ScriptManager" runat="server" ScriptMode="Release">
                <CompositeScript>
                    <Scripts>
                        <asp:ScriptReference Path="~/Scripts/jquery-1.7.2.min.js" />
                        <asp:ScriptReference Path="~/Scripts/jquery.ui.core.min.js" />
                        <asp:ScriptReference Path="~/Scripts/jquery.ui.widget.min.js" />
                        <asp:ScriptReference Path="~/Scripts/jquery.ui.mouse.min.js" />
                        <asp:ScriptReference Path="~/Scripts/jquery.ui.sortable.min.js" />
                    </Scripts>
                </CompositeScript>
 </asp:ScriptManager>

علاوه بر آن حتما خاصیت ScriptMode کنترل ScriptManager  را بر روی Release تنظیم نمایید تا از حداکثر کارایی و کش فایل‌ها استفاده نمایید

دسترسی به ScriptManager در صفحات دیگر و الصاق فایل‌های خاص

برخی از فایل‌های Javascript فقط در صفحات خاصی استفاده شده اند و لازم نیست در هر صفحه بارگذاری شود برای این کار کافی است فایل مورد نظر را در صفحه خاص به  ScriptManager اضافه نمایید. البته ابتدا لازم است به ScriptManager دسترسی داشته باشیم. کد زیر نحوه دسترسی به آن را نمایش داده است:

ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
scriptManager.CompositeScript.Scripts.Add(new ScriptReference("~/Scripts/jquery.json.min.js"));
ادامه دارد...