بازخوردهای دوره
ارائه کاربری ساده‌تر انتخاب چندین آیتم از یک لیست به کمک افزونه TagIt در ASP.NET MVC
بسیار عالی .
بعد از خوندن مطلب ، اول فکر کردم که استفاده از jQuery UI ضروری نیست و فقط در صورتی که بخوایم امکان autoComplete رو فعال کنیم باید رفرنسی به اون بدیم اما بعد از حذف کردن متوجه شدم که اینطور نیست و کلا این plugin هم به jQuery و هم به jQuery UI وابسته است و بدون UI کار نمی‌کنه .


نظرات مطالب
مروری بر کتابخانه ReactJS - قسمت هفتم - ورودی‌های کاربر
خطای 415 از سمت سرور یعنی unsupported media type. مطلب «جایگزین کردن jQuery با JavaScript خالص - قسمت پنجم - درخواست‌های Ajax» را مطالعه کنید تا با معادل‌های قبلی و جدید fetch api و نحوه‌ی صحیح تنظیم و «کار با JSON Encoding» آشنا شوید (headers: {'Content-Type': 'application/json'}). همچنین می‌تواند مشکل CORS و عدم تنظیم آن هم باشد (اگر برنامه‌ی کلاینت روی پورت x و برنامه‌ی سرور روی پورت y اجرا می‌شود و این دو پورت یکی نیستند).
مطالب
لینک‌های هفته آخر آذر

وبلاگ‌ها و سایت‌های ایرانی


امنیت


Visual Studio


ASP. Net


طراحی وب


PHP

  • Aptana PHP 1.0 منتشر شد (اگر قبلا این IDE بسیار قابل توجه را دریافت کرده بودید فقط کافی است به منوی aptana و گزینه my aptana مراجعه کرده و از قسمت plugins ، این پلاگین 18 مگابایتی را دریافت کنید.)

اس‌کیوال سرور


سی شارپ


عمومی دات نت


ویندوز


متفرقه


پاسخ به بازخورد‌های پروژه‌ها
مشکل در bundle and minification در هاست
باید بتوانید برنامه را دیباگ کنید:
- فایل‌های خالی، به همراه خطای مرتبط هم هستند: نحوه استفاده از افزونه Firebug برای دیباگ برنامه‌های ASP.NET مبتنی بر jQuery  
- این پروژه برای لاگ خطاهای سمت سرور از ELMAH استفاده می‌کند. لاگ‌های آن‌را بررسی کنید.
نظرات مطالب
نمایش فرم‌های مودال Ajax ایی در ASP.NET MVC به کمک Twitter Bootstrap
این مورد پیش بینی شده در این مثال. اگر به خروجی اکشن متد دقت کنید، چنین چیزی است:
return Json(new { success = true });
همین مورد یعنی بررسی مقدار success دریافتی، جایی که عملیات Ajax ایی ارسال اطلاعات پایان می‌یابد انجام شده:
if (result.success) {
                            $('#dialogDiv').modal('hide');
                            if (options.completeHandler)
                                options.completeHandler();
بنابراین تنها کاری که باید انجام بدید، قرار دادن کدهای نمایش اطلاعات نهایی در callbackهای completeHandler ویا errorHandler مربوط به افزونه  $.bootstrapModalAjaxForm است. اینجا دست شما باز است. اگر علاقمند بودید از یک alert ساده استفاده کنید یا از همین روش نمایش صفحات مودال به نحوی دیگر یا از صدها افزونه jQuery موجود برای نمایش پیام‌ها.

مطالب
فشرده سازی فایل های CSS و JavaScript بصورت خودکار توسط MS Ajax Minifier
با توجه به افزایش کاربرد jQuery و دیگر کتابخانه‌های جاوا اسکریپت در برنامه‌های تحت وب، یکی از چالش‌های همیشگی برنامه نویسان، فشرده سازی فایل‌های دربرگیرنده کدهای جاوا اسکریپت و شیوه نامه‌ها  می باشد. برای این منظور راه‌های مختلفی مانند استفاده از ابزارهای آنلاین مانند این +  و این +  وجود دارند. اما یک روش خودکار هم وجود دارد که در زمان Build پروژه‌های دات نت می‌توان از آن بهره گرفت.

Microsoft Ajax Minifier
یک ابزار رایگان جهت فشرده سازی فایل‌های جاوا اسکریپت و شیوه نامه‌ها است. شما می‌توانید این ابزار را از صفحه خانگی آن در سایت asp.net دریافت کنید. جهت استفاده از این ابزار می‌توان از طریق خط فرمان عمل کرد. اما روش ساده‌تر که هدف اصلی این مطلب است به شرح زیر است:
1. در VisualStudio.NET از طریق منو به مسیر Tools, Options, Projects and Solutions بروید و گزینه Always show solution را تیک بزنید.

2. از Solution Explorer بر روی عنوان پروژه کلیک راست کرده و گزینه Unload Project را انتخاب نمایید.

3. مجدداً روی عنوان پروژه کلیک راست کرده و گزینه Edit را انتخاب کنید و دستورات زیر را قبل از بسته شدن تگ Project اضافه کنید:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
<Target Name="AfterBuild">
<ItemGroup>
  <JS Include="**\*.js" Exclude="**\*.min.js;Scripts\*.js" />
</ItemGroup>
<ItemGroup>
  <CSS Include="**\*.css" Exclude="**\*.min.css" />
</ItemGroup>
<AjaxMin 
    JsSourceFiles="@(JS)"  JsSourceExtensionPattern="\.js$" JsTargetExtension=".min.js"
    CssSourceFiles="@(CSS)" CssSourceExtensionPattern="\.css$" CssTargetExtension=".min.css"  />
</Target>
4. دوباره بر روی عنوان پروژه کلیک راست کرده و گزینه Reload Project را انتخاب کنید.
توجه کنید که با این کار ما یک MSBuild task با عنوان ajaxmini به پروژه اضافه کردیم. این وظیفه که در زمان Build پروژه اجرا خواهد شد فایل‌های جاوا اسکریپت را فشرده و با پسوند .min.js و همچنین فایل‌های CSS را پس از فشرده سازی با پسوند .min.css در همان مسیر فایل مادر بطور خودکار ذخیره می‌کند.

نکته:
اگر به دستورات تنظیمات فوق نگاه دقیقتری بیندازیم، متوجه عبارات Include و Exclude می شویم. توسط این دو صفت شما می‌توانید الگوهایی را جهت فشرده سازی و یا عدم فشرده سازی تعریف کنید. بدین معنا که توسط الگوی‌های ذکر شده در تنظیمات فوق از فشرده سازی فایل‌های با پسوند .min.css و .min.js خودداری می‌شود.
در این شرایط در حین توسعه برنامه، شما می‌توانید از فایل‌های با کد خوانا استفاده نمایید و زمان انتشار و Build پروژه بصورت خودکار آنها را با فایل‌های فشرده جایگزین کنید.
این ابزار تمامی فضاهای خالی، ';‌' و '{ }'‌های اضافی و توضیحات را از کدهای شما حذف می‌کند. متغیر‌ها و توابع شما را به اسامی کوجک‌تر تغییر نام می‌دهد. و ...  
همچنین شما از کتابخانه این پروژه می‌توانید در زمان اجرا و سورس برنامه خود استفاده کنید. جهت اطلاعات بیشتر می‌توانید به سایت مربوطه  مراجعه نمایید.
 
مطالب
React 16x - قسمت 34 - توزیع برنامه
در قسمت آخر این سری، نگاهی خواهیم داشت به نحوه‌ی توزیع برنامه‌های React و نکات مرتبط با آن.


افزودن متغیرهای محیطی

در برنامه‌ی نمایش لیست فیلم‌هایی که تا قسمت 29 آن‌را بررسی کردیم، از فایل src\config.json برای ذخیره سازی اطلاعات تنظیمات برنامه استفاده شد. هرچند این روش کار می‌کند اما بر اساس محیط‌های مختلف توسعه، متغیر نیست. اغلب برنامه‌ها باید بتوانند حداقل در سه محیط توسعه، آزمایش و تولید، بر اساس متغیرها و تنظیمات خاص هر کدام، کار کنند. برای مثال بر روی سیستمی که کار توسعه در آن انجام می‌شود، می‌خواهیم apiUrl متفاوتی را نسبت به حالتیکه برنامه توزیع می‌شود، داشته باشیم.
برای رفع این مشکل، برنامه‌هایی که توسط create-react-app تولید می‌شوند، دارای پشتیبانی توکاری از متغیرهای محیطی هستند. برای این منظور نیاز است در ریشه‌ی پروژه (جائیکه فایل package.json قرار دارد) فایل جدید env. را ایجاد کرد. در ویندوز برای ایجاد یک چنین فایل‌هایی که فقط از یک پسوند تشکیل می‌شوند، باید نام فایل را به صورت .env. وارد کرد؛ سپس خود ویندوز نقطه‌ی نهایی را حذف می‌کند. البته اگر از ادیتور VSCode برای ایجاد این فایل استفاده می‌کنید، نیازی به درج نقطه‌ی انتهایی نیست. در این فایل environment ایجاد شده می‌توان تمام متغیرهای محیطی مورد نیاز را با مقادیر پیش‌فرض آن‌ها درج کرد. همچنین می‌توان این مقادیر پیش‌فرض را بر اساس محیط‌های مختلف کاری، بازنویسی کرد. برای مثال می‌توان فایل env.development. را اضافه کرد؛ به همراه فایل‌های env.test. و env.production.


متغیرهای محیطی به صورت key=value درج می‌شوند. این کلیدها نیر باید با REACT_APP_ شروع شوند؛ در غیر اینصورت، کار نخواهند کرد. برای مثال در فایل env.، دو متغیر پیش‌فرض زیر را تعریف می‌کنیم:
REACT_APP_NAME=My App
REACT_APP_VERSION=1
اکنون برای خواندن این متغیرها برای مثال در فایل index.js (و یا هر فایل جاوا اسکریپتی دیگری در برنامه)، سطر زیر را درج می‌کنیم:
console.log(process.env);
process به معنای پروسه‌ی جاری برنامه‌است (و مرتبط است به پروسه‌ی node.js ای که برنامه‌ی React را اجرا می‌کند) و خاصیت env، به همراه تمام متغیرهای محیطی برنامه می‌باشد. در این حالت اگر برنامه را اجرا کنیم، در کنسول توسعه دهندگان مرورگر، به یک چنین خروجی خواهیم رسید:


در این خروجی، متغیر "NODE_ENV: "development به صورت خودکار با تولید بسته‌های مخصوص ارائه‌ی نهایی، به production تنظیم می‌شود. سایر متغیرهای محیطی تعریف شده را نیز در اینجا ملاحظه می‌کنید. با توجه به خواص شیء env، برای مثال جهت دسترسی به نام برنامه می‌توان از مقدار process.env.REACT_APP_NAME استفاده کرد.


یک نکته: با هر تغییری در مقادیر متغیرهای محیطی، نیاز است یکبار دیگر برنامه را از ابتدا توسط دستور npm start، راه اندازی مجدد کرد؛ چون این فایل‌ها به صورت خودکار ردیابی نمی‌شوند.


نحوه‌ی پردازش متغیرهای محیطی درج شده‌ی در برنامه

اگر همان سطر لاگ کردن خروجی process.env را به صورت زیر تغییر دهیم:
console.log("My App Name", process.env.REACT_APP_NAME);
و برنامه را مجددا اجرا کنیم، با مراجعه‌ی به برگه‌ی Sources و انتخاب مسیر localhost:3000/static/js/main.chunk.js و سپس جستجوی "My App Name" ای که در اینجا اضافه کردیم (با فشردن دکمه‌های Ctrl+F)، به خروجی زیر خواهیم رسید:


همانطور که مشاهده می‌کنید، فراخوانی console.log ما، دیگر به همراه متغیر process.env.REACT_APP_NAME نیست؛ بلکه مقدار اصلی این متغیر در اینجا درج شده‌است. بنابراین اگر در در حین توسعه‌ی برنامه، از متغیرهای محیطی استفاده شود، این متغیرها با مقادیر اصلی آن‌ها در حین پروسه‌ی Build نهایی، جایگزین می‌شوند.


Build برنامه‌های React برای محیط تولید

اجرای دستور npm start، سبب ایجاد یک Build مخصوص محیط توسعه می‌شود که بهینه سازی نشده‌است و به همراه اطلاعات اضافی قابل توجهی جهت دیباگ ساده‌تر برنامه‌است. برای رسیدن به یک خروجی بهینه سازی شده‌ی مخصوص محیط تولید و ارائه‌ی نهایی باید دستور npm run build را در خط فرمان اجرا کرد. خروجی نهایی این دستور، در پوشه‌ی جدید build واقع در ریشه‌ی پروژه، قرار می‌گیرد. اکنون می‌توان کل محتویات این پوشه را جهت ارائه‌ی نهایی در وب سرور خود، مورد استفاده قرار داد.
پس از پایان اجرای دستور npm run build، پیام «امکان ارائه‌ی آن توسط static server زیر نیز وجود دارد» ظاهر می‌شود:
> npm install -g serve
> serve -s build
اگر علاقمند باشید تا خروجی حالت production تولید شده را نیز به صورت محلی آزمایش کنید، ابتدا باید static server یاد شده را توسط دستور npm install فوق نصب کنید. سپس ریشه‌ی پروژه را در خط فرمان باز کرده و دستور serve -s build را صادر کنید (البته اگر با خط فرمان به پوشه‌ی build وارد شدید، دیگر نیازی به ذکر پوشه‌ی build نخواهد بود). اکنون می‌توانید برنامه را در آدرس http://localhost:5000 در مرورگر خود بررسی نمائید.

البته با توجه به اینکه backend سرور برنامه‌های ما نیز در همین آدرس قرار دارد و در صورت ورود این آدرس، به صورت خودکار به https://localhost:5001/index.html هدایت خواهید شد، می‌توان این پورت پیش‌فرض را با اجرای دستور  serve -s build -l 1234 تغییر داد. اکنون می‌توان آدرس جدید http://localhost:1234 را در مرورگر آزمایش کرد که ... با خطای زیر کار نمی‌کند:
Access to XMLHttpRequest at 'https://localhost:5001/api/genres' from origin 'http://localhost:1234' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
روش رفع این مشکل را در قسمت 23 بررسی کردیم و در اینجا جهت بهبود آن می‌توان متد WithOrigins فایل Startup.cs را به صورت زیر تکمیل کرد:
WithOrigins("http://localhost:3000", "http://localhost:1234")

یک نکته: زمانیکه از دستور npm start استفاده می‌شود، متغیرهای محیطی از فایل env.development. خوانده خواهند شد و زمانیکه از دستور npm run build استفاده می‌شود، این متغیرها از فایل env.production. تامین می‌شوند. در این حالت‌ها اگر متغیری در این دو فایل درج نشده بود، از مقدار پیش‌فرض موجود در فایل env. استفاده می‌گردد. از فایل env.test. با اجرای دستور npm test، به صورت خودکار استفاده می‌شود.


آماده سازی برنامه‌ی React، برای توزیع نهایی

تا اینجا برنامه‌ی React تهیه شده، اطلاعات apiUrl خودش را از فایل config.json دریافت می‌کند. اکنون می‌خواهیم بر اساس حالات مختلف توسعه و تولید، از apiUrlهای متفاوتی استفاده شود. به همین جهت به فایل env.production. مراجعه کرده و تنظیمات ذیل را به آن اضافه می‌کنیم:
REACT_APP_API_URL=https://localhost:5001/api
REACT_APP_ADMIN_ROLE_NAME=Admin
البته فعلا همین متغیرها را به فایل env.development. نیز می‌توان اضافه کرد؛ چون backend سرور ما در هر دو حالت، در این مثال، در آدرس فوق قرار دارد.

اکنون به برنامه مراجعه کرده و در هرجائی که ارجاعی به فایل config.json وجود دارد، سطر import آن‌را حذف می‌کنیم. با این تغییر، تمام آدرس‌هایی مانند:
const apiEndpoint = apiUrl + "/users";
را به صورت زیر ویرایش می‌کنیم:
const apiEndpoint =  "/users";
در ادامه برای تامین مقدار apiUrl به صورت خودکار، به فایل src\services\httpService.js مراجعه کرده و در ابتدای آن، یک سطر زیر را اضافه می‌کنیم:
 axios.defaults.baseURL = process.env.REACT_APP_API_URL;
به این ترتیب تمام درخواست‌های ارسالی توسط Axios، دارای baseURL ای خواهند شد که از فایل متغیر محیطی جاری تامین می‌شود. همانطور که پیش‌تر نیز عنوان شد، این مقدار در زمان Build، با مقدار ثابتی که از فایل env جاری خوانده می‌شود، جایگزین خواهد شد.
همچنین adminRoleName مورد نیاز در فایل src\services\authService.js را نیز از همان فایل env جاری تامین می‌کنیم:
const adminRoleName =  process.env.REACT_APP_ADMIN_ROLE_NAME;
پس از این تغییرات، نیاز است برای حالت توسعه، یکبار دیگر دستور npm start و یا برای حالت تولید، دستور npm run build را اجرا کرد تا اطلاعات درج شده‌ی در فایل‌های env.، پردازش و جایگزین شوند.


کدهای کامل این قسمت را از اینجا می‌توانید دریافت کنید: sample-34-frontend.zip و sample-34-backend.zip