نظرات مطالب
اعتبارسنجی مبتنی بر JWT در ASP.NET Core 2.0 بدون استفاده از سیستم Identity
- در مقدمه مطلب «ذخیره سازی اطلاعات در مرورگر توسط برنامه‌های Angular» در مورد محدودیت حجم‌های حالت‌های مختلف ذخیره سازی اطلاعات در سمت کلاینت، بیشتر توضیح داده شده‌است.
- روش پیاده سازی dynamic permission شما و قرار دادن اطلاعات آن در توکن، در این حالت بی‌مورد است. از این جهت که به نظر قصد ندارید از اطلاعات آن در سمت کلاینت استفاده کنید (محدود کردن دسترسی به صفحات یک برنامه‌ی SPA و نه یک برنامه‌ی MVC). توکن و هرچیزی که در آن است جهت کاربردهای سمت کلاینت بیشتر باید مورد استفاده قرارگیرند تا سمت سرور. این بحث JWT برای برنامه‌های Angular و کلا SPA (تک صفحه‌ای وب) بیشتر استفاده می‌شود (سمت سرور Web API خالص، سمت کاربر SPA خالص). اگر برنامه‌ی شما چنین چیزی نیست، از آن استفاده نکنید.
چون اطلاعات دسترسی به صفحات به نظر سایت MVC شما مطلقا کاربردی در سمت کلاینت ندارند، آن‌را به توکن اضافه نکنید. در عوض در متد CanUserAccess، قسمت user.HasClaim را با کوئری گرفتن از بانک اطلاعاتی جایگزین کنید.
- مثال سمت کلاینت بحث جاری در سری «احراز هویت و اعتبارسنجی کاربران در برنامه‌های Angular» عمیق‌تر بررسی شده‌است و هدف از قسمت‌های مختلف توکن آن‌را جهت استفاده‌ی در سمت کلاینت (استفاده از نقش‌ها جهت دسترسی به صفحات برنامه‌ی سمت کلاینت Angular، استفاده از تاریخ انقضای توکن جهت بررسی اعتبار آن، استفاده از نام نمایشی قرار گرفته‌ی در توکن برای نمایش آن در سمت کلاینت و غیره)، بهتر درک خواهید کرد. در سمت سرور با داشتن Id شخص، مابقی را می‌توان از بانک اطلاعاتی کوئری گرفت و نیازی به سنگین کردن توکن نیست.
نظرات مطالب
پَرباد - آموزش پیاده‌سازی پرداخت آنلاین در دات نت - آموزش پیشرفته
این مورد قبلا هم توسط افراد دیگری عنوان شده بوده و من سعی میکنم اینجا یه توضیح مختصر برای شما و سایرین بدم، چون این مورد بیشتر جنبه توصیه طراحی سیستم داره تا کار کردن با این ابزار.

همونطور که مطلع هستین پَرباد برای بانک اطلاعاتی از EntityFramework استفاده می‌کنه. بنابراین این پروژه Migrations‌های مخصوص به خودش رو داره که با هر آپدیت میتونن اعمال بشن. در نتیجه شما نمی‌تونید با پروژه خودتون Merge کنید. 

بانک اطلاعاتی پَرباد فقط جنبه مصرف داخلی داره. اما حتی اگر اینگونه هم نبود، شما نباید طراحی سیستم خودتون رو بر اساس یک کتابخانه (پَرباد و یا هر کتابخانه دیگری) انجام بدید. طراحی سیستم شما باید کاملا مستقل از هر ابزاری باشه.
به این علت که:
  1. این ابزار توسط اشخاص دیگری توسعه داده شده نه شما و این یعنی هر لحظه امکان تغییر سراسری اون ابزار توسط توسعه دهندگانش هست. در نتیجه هر لحظه‌ای که اون ابزار تغییری پیدا بکنه، شما هم باید طراحی سیستم خودتون رو تغییر بدید.
  2. ذخیره اطلاعات یک پرداخت باید توسط شما در بانک اطلاعاتی شما انجام بشه، اطلاعاتی که پَرباد در بانک اطلاعاتی خودش ذخیره و بازبابی می‌کنه، صرفا جنبه مصرف داخلی برای خودش رو داره.

اما در مورد اطلاعاتی که شما در پایگاه داده خودتون نیاز دارید، این اطلاعات طبیعتا اصلی‌ترین داده‌های یک پرداخت هست. یعنی: کد رهگیری، کد تراکنش بانکی، نام بانک، مبلغ و  غیره. بنابراین برای مثال اگر شما نیاز به یک کلید اصلی پرداخت دارید، باید کد رهگیری (که پس از ارسال یک درخواست پرداخت می‌تونید از پَرباد دریافت کنید) رو به عنوان کلید اصلی در جدول خودتون ثبت کنید.

اگر بخوام کامل و مرحله‌ای براتون توضیح بدم، عملیات استاندارد خرید یا سفارش به صورت زیر هست:

  1. شما از قبل طراحی بانک اطلاعاتی خودتون رو بدون در نظر گرفتن هیج گونه ابزار خارجی (پَرباد) انجام داده‌اید. (پَرباد یک ابزار پرداخت هست و برای اون اهمیتی نداره پرداخت در سیستم مصرف کننده به چه شکلی طراحی شده. وظیفه او فقط انجام عملیات پرداخت آنلاین هست)
  2. مبلغ قابل پرداخت رو مشخص می‌کنید و درخواست پرداخت رو توسط پَرباد انجام میدید.
  3. نتیجه درخواست پرداخت که شامل کد رهگیری و غیره هست رو در بانک اطلاعاتی خودتون ثبت می‌کنید. (برای فاکتور مورد نظر)
  4. کاربر به درگاه بانکی هدایت میشه،  هزینه رو پرداخت می‌کنه و به وب سایت شما برمیگرده.
  5. عملیات تایید پرداخت رو توسط پَرباد انجام میدید.
  6. پس از تایید، کلیه اطلاعات لازم مانند کد رهگیری، کد تراکنش بانکی، مبلغ و غیره رو از پَرباد دریافت می‌کنید و در بانک اطلاعاتی خودتون ذخیره می‌کنید (با توجه به کد رهگیری که در مرحله ۳ ذخیره کرده بودید، اطلاعات فاکتور مورد نظرتون رو آپدیت می‌کنید)

بازخوردهای پروژه‌ها
اعمال نشدن حذف رکورد بر روی دیتاتیبل
با سلام و تشکر

در کلیه قسمت‌های مدیریت که اطلاعات به شکل یک جدول نمایش داده شده است(به عنوان مثال لیست کاربران سایت) هنگام حذف یک رکورد،یک دیالوگ تایید نمایش داده می‌شود و پس از تایید رکورد از بانک اطلاعاتی حذف می‌گردد اما کماکان در لیست رکوردها نشان داده میشود و پس از رفرش رکورد مورد نظر از لیست حذف می‌گردد
آیا این امکان وجود دارد که موقع حذف لیست مورد نظر بروز گردد
مطالب
فقط به خاطر یک نیم فاصله!
نسخه‌ی 64 بیتی ویندوز 7 را نصب کرده‌ام و اولین مشکل، نبود صفحه کلید مطابق استاندارد 2091 برای نسخه‌های 64 بیتی ویندوز است. پروژه وب فارسی دانشگاه صنعتی شریف، سال‌ها قبل فقط یک نسخه‌ی 32 بیتی از آن را تهیه کرده و نسخه‌های 64 بیتی موجود، مطابق استاندارد 9147 هستند و من به دلایل ذیل حاضر به استفاده از آن نیستم!
  1. در استاندارد 9147 ، جای ژ و پ مطابق صفحه کلیدی که در بازار ایران فروخته می‌شود نیست (و باید به همه پاسخگو باشید که چرا اینطوری است).
  2. ی و ک در آن اصلاح شده و دیگر عربی نیست که چقدر هم خوب، اما من تعداد زیادی برنامه و همچنین تعداد قابل توجهی فایل word دارم که مطابق استاندارد 2091 تهیه شده‌اند. مشکلات ی و ک فارسی و عربی را هم در اینجا ذکر کرده‌ام و به دنبال باگ‌های جدید در برنامه‌ها نمی‌گردم.
  3. با ی و ک فارسی اگر در گوگل جستجو کنید تعداد پاسخ‌های مرتبط یافت شده بسیار بسیار کمتر از حالتی خواهد بود که با ی و ک عربی جستجو کنید.
  4. در یک سازمان باید رویه‌ا‌ی واحد در این مورد برقرار باشد. یا همه باید از 2091 استفاده کنند و یا همه از 9147.

نسخه‌ی کامل استاندارد 9147 را از سایت آقای اخگری می‌توانید دریافت نمائید:

به همین دلایل خصوصا قسمت دوم (هر چند ممکن است با آن موافق نباشید)، نیاز به صفحه کلید مطابق استاندارد 2091 نسخه‌ی 64 بیتی داشتم.

برای تهیه صفحه کلید فارسی از برنامه Microsoft Keyboard Layout Creator استفاده می‌شود که نسخه‌ی 1.4 آن‌را از آدرس زیر می‌توانید دریافت نمائید. این نسخه قابلیت تولید فایل‌های dll مرتبط 64 بیتی را هم دارد:


یکی از قابلیت‌های این برنامه بارگذاری صفحه کلید فارسی جاری سیستم است:



صفحه کلید استاندارد 2091 پروژه وب فارسی را اگر با آن باز کرده و سپس از منوی Project گزینه‌ی Build DLL and setup package را انتخاب نمائید، با خطای زیر متوقف خواهید شد:
ERROR: 'VK_SPACE' in Shift State 'Shift' must be made up of white space character(s), but is defined as '‌' (U+200c) instead.
که دقیقا مربوطه به این سطر در تعاریف صفحه کلید است (صفحه کلید را می‌شود به صورت فایلی با پسوند klc هم save as کرد):
39 SPACE  0 0020 200c 0020 -1  // SPACE, ZERO WIDTH NON-JOINER, SPACE, <none>
مفاهیم این ستون‌ها هم به شرح زیر هستند:
0 //Column 4
1 //Column 5 : Shft
2 //Column 6 :       Ctrl
3 //Column 7 : Shft  Ctrl
یعنی جهت نمایش نیم فاصله حاصل از ترکیب shift space مطابق استاندارد تایپ ایران، بجای 0x0020 یا همان فاصله، از 0x200C استفاده شده است (مطابق استاندارد تایپ ایران باید نوشت "می‌روم" و نه "می روم". به نیم فاصله و فاصله دقت بفرمائید).
اما این برنامه‌ی محترم دقیقا همین مورد را غلط گرفته و فایل dll نهایی را تولید نمی‌کند (مطابق خطایی که ذکر شد).
برنامه‌ی Microsoft Keyboard Layout Creator هم با دات نت فریم ورک نوشته شده است. اگر کمی با reflector به آنالیز آن بپردازیم به کلاس Accept و متد زیر خواهیم رسید:
private bool VerifySpaceBarIntegrity(ShiftState ss, bool fMustBeDefined)
در این متد جایی که خطای ذکر شده صادر می‌شود، مربوط به چند سطر زیر است:
if (!Utilities.IsSpacing(ss.Characters))
{
    this.WriteErrorToLogFile("SpaceKeyNeedsWhiteSpaceCharacters", new string[] { "VK_" + Utilities.VkStringOfIvk(ss.VK), this.m_stStateLabel[ss.State], ss.Characters, Utilities.FromCharacterToUPlusForm(ss.Characters) });
    flag = false; /*اینجا باید اصلاح شود!*/
}
خوب! به نظر شما ایرادی دارد که این flag همیشه true باشد؟! برای همین منظور، فایل MSKLC.exe را پچ کرده‌ام که از آدرس زیر قابل دریافت است:

  دریافت پچ شده نگارش 1.4.6000.2 : MSKLC.Patched.7z  

با استفاده از این نسخه (ابتدا برنامه اصلی را نصب کرده و سپس فایل exe را جایگزین نمائید)، به راحتی می‌توان نسخه‌ی استاندارد و اصلی 2091 را بارگذاری و مجددا کامپایل کرد (بدون توقف کامپایل به خاطر فقط یک نیم فاصله‌ی غیرمعتبر از دیدگاه نویسندگان اصلی برنامه). به این صورت فایل‌های 64 بیتی لازم هم تولید می‌شوند ( ممکن است در حین کار با برنامه‌ی patch شده، نمایش خطای کار با نیم فاصله را مجددا دریافت کنید؛ اما مهم نیست . نمونه‌ی وصله شده، بدون مشکل حاصل را کامپایل می‌کند که در نمونه‌ی اصلی اینطور نیست. یعنی پس از overwrite کردن فایل exe موجود، با نمونه patch شده، برنامه کار کامپایل را کامل می‌کند) که حاصل نهایی را از آدرس زیر می‌توانید دریافت نمائید:


این فایل‌ها دقیقا بر مبنای همان فایل‌های پروژه وب فارسی استاندارد 2091 هستند؛ با این تفاوت که نسخه‌‌های غیر 32 بیتی هم در آن لحاظ شده‌اند.

نصب این dll‌ها هم از ویندوز ویستا به بعد داستان خودش را پیدا کرده؛ ابتدا باید take ownership شود، سپس می‌توان فایل اصلی را به سادگی جایگزین کرد و سپس reboot .
برای این منظور ابتدا به پوشه‌ی system32 ویندوز مراجعه کرده و فایل KBDFA.DLL را پیدا کنید.
در ادامه به پنجره خواص آن (کلیک راست و انتخاب properties) مراجعه و برگه‌ی Security آن‌را انتخاب کنید.
در این قسمت بر روی دکمه‌ی Advanced کلیک نمائید.
در صفحه‌ی باز شده به برگه‌ی Owner مراجعه کنید.
در این قسمت بر روی دکمه‌ی Edit کلیک نموده و کاربر خودتان را اضافه نمائید.
پس از طی این مرحله (یا همان take ownership) به برگه security مراجعه کرده و به کاربر خودتان دسترسی full control بدهید.
اکنون مجوز تغییر این فایل را بدون هیچ مشکلی خواهید یافت.
در پایان reboot را فراموش نکنید.

راه دوم:
یا برنامه نصاب حاصل از برنامه‌ی Microsoft Keyboard Layout Creator، مدخل جدیدی را به صفحه کلیدهای قابل انتخاب ویندوز در کنترل پنل اضافه می‌کند که نیازی به reboot ندارد.
اشتراک‌ها
معرفی و بررسی پروتکل HTTP2 از نظر فنی

پروتکل (Hyper Text Transfer Protocol (HTTP (انتقال فوق متن) پروتکلی است که وظیفه انتقال (ارسال و دریافت) داده‌ها بین کلاینت و سرور را بر عهده دارد. منظور از کلاینت مرورگر وب و منظور از سرور یک وب سایت اینترنتی است. در واقع پروتکل انتقال ابر متن زبان مشترک بین سرویس دهندگان و سرویس گیرندگان وب است و شامل مجموعه ای از قوانین است که برای انتقال انواع فایل‌ها مثل صدا، متن، عکس و... برای انتقال در شبکه وب استفاده می‌شود.

مستند لینک بالا مزیتها و بهینه سازی هایی که در پروتکل HTTP2 نسبت به نسخه قبل از آن انجام شده است را مورد بررسی قرار می‌دهد.


سوالات متداول در خصوص HTTP2

 

معرفی و بررسی پروتکل HTTP2 از نظر فنی
مطالب
بررسی چک لیست امنیتی web.config
در مقاله چک لیست امنیتی web.config متوجه شدیم که تنظیم یک سری مقادیر، باعث افزایش ضریب ایمنی وب سایت می‌شود. در این نوشتار قصد داریم به بررسی این چک لیست امنیتی بپردازیم.
اولین مورد لیست در رابطه با وضعیت session هاست؛ هر چند که توصیه میشود تا جای ممکن استفاده از session‌ها کنار گذاشته شود یا اینکه محدود شود .
  
SessionState
تگ sessionstate حاوی خصوصیتی به نام cookieless میباشد که در نسخه‌ی یک دات نت به صورت دو ارزشی پیاده سازی شده بود و با دادن مقدار false باعث میشد که سشن‌ها از طریق کوکی‌ها شناسایی شوند و در صورت true شدن، استفاده کوکی مسدود و از طریق url کنترل میشد. در نسخه دو دات نت، گزینه‌های این خصوصیت گسترده‌تر شد و مقادیر مختلفی اضافه شدند؛ مانند: شناسایی خودکار (در صورت عدم پشتیبانی مرورگر از کوکی) ، استفاده از کوکی و استفاده از URL.
استفاده در حالت url باعث میشود تا عبارات نامفومی که ما به آن sessionId می‌گوییم در بخشی از url به شکل زیر گنجانده شود:
https://www.dntips.ir/(xxxxxx)/page.aspx
استفاده از این حالت باعث مشکلات متعددی است؛ چه از لحاظ امنیتی و سایر موارد.
1- به دلیل تنوع لینکی که توسط این sessionID‌ها به ازای هر کاربر ایجاد میشوند، در نظر موتورهای جست و جو لینک‌هایی متفاوت محسوب شده و باعث کاهش جایگاه میگردد.
2- در صورتیکه آدرس دهی‌های شما بدون ذکر sessionID باشند، سرور کاربر مورد نظر را شناسایی نکرده و برای او session جدید صادر خواهد کرد. برای افزودن sessionID به لینک‌ها و اصلاح آن‌ها میتوان از متد زیر استفاده کرد:
Response.ApplyAppPathModifier
3- در صورت embed کردن sessionID در آدرس فایل‌های استاتیک، عملیات کش کردن نیز با مشکل مواجه خواهد شد.
4- در صورتی که session  معتبر باشد و لینکی از آن ارسال شود، کاربری دیگر، همان کاربر مبداء در نظر گرفته خواهد شد. نمونه این مسئله برای من اتفاق افتاده بود که در آن یکی از دوستان، لینکی از یکی از سازمان‌های دولتی را برای من ارسال کرده بود که حاوی sessionId بود تا قادر باشم وجه مورد نظر را به صورت آنلاین پرداخت کنم. بعد از اینکه من لاگین کردم، session او با کد کاربری من پر شد و در همان حین دوست من با یک refresh به جای اطلاعات خودش ، اطلاعات پرداختی‌های من را مشاهده میکرد.
در صورتی که از session استفاده نمیکنید، بهترین حالت غیرفعال کردن این گزینه میباشد.
  
HttpOnly Cookie
httpOnly برای کوکی‌ها، در واقع یک فلگ است که از سوی مایکروسافت معرفی شده و در حال حاضر اکثر مرورگرها از این گزینه پشتیبانی میکنند. این فلگ باعث میشود که کوکی در مرورگر دیگر از طریق اسکریپت‌های سمت کلاینت در دسترس نبوده و تنها از طریق ارتباط با سرور در دسترس قرار گیرد. نحوه افزودن این فلگ را در دستور زیر مشاهده میکنید:
Set-Cookie: <name>=<value>[; <Max-Age>=<age>]
[; expires=<date>][; domain=<domain_name>]
[; path=<some_path>][; secure][; HttpOnly]
با افزودن این فلگ، دامنه حملات سمت کلاینت به خصوص XSS کاهش پیدا کرده و امکان جابجایی کوکی بین مرورگرها از بین خواهد رفت. طبق گفته‌ی مایکل هوارد، یکی از مدیران امنیتی خانواده ویندوز، بیشتر این نوع حملات، صرف کوکی‌های سشن میباشد. در صورتیکه کوکی به فلگ httponly مزین شده باشد، حمله کننده قادر نخواهد بود از طریق کلاینت، دیتای داخل کوکی را بخواند و بجای آن، یک رشته‌ی خالی را تحویل گرفته و به سمت حمله کننده ارسال خواهد کرد.
در دات نت دو، این امکان برای forms Authentication  و همچنین session Id به طور خودکار لحاظ میگردد و این امکان از طریق وب کانفیگ در دسترس است:
<httpCookies httpOnlyCookies="true" …>
همچنین به شکل زیر از طریق کدنویسی امکان اعمال این فلگ بر روی کوکی‌ها امکان پذیر میباشد:
HttpCookie myCookie = new HttpCookie("myCookie");
myCookie.HttpOnly = true;
Response.AppendCookie(myCookie);
در نگارش‌های ماقبل دات نت دو باید این مورد را دستی به کوکی اضافه کرد که آقای هانسلمن در  وبلاگش این مورد را به طور کامل ذکر کرده است.
  
Custom Errors Mode
این مورد برای مشخص شدن وضعیت نمایش خطاها ایجاد شده است. در صورت خاموش کردن (Off) این گزینه، چه بر روی لوکال و چه بر روی سرور میزبان، خطاهای صفحه زرد رنگ به کاربران نمایش داده خواهد شد و از آنجا که این صفحه اطلاعات حیاتی و مهمی برای نمایش دارند، بهتر است که این صفحه از دید کابران نهایی مخفی شده و با ست کردن این گزینه روی On، صفحات خاصی که برای خطا مشخص کرده‌ایم نمایش پیدا می‌کنند و در صورتی که remoteOnly باشد، باعث می‌شود صفحه زرد رنگ تنها در حالت لوکال به نمایش در بیاید؛ ولی بر روی سرور تنها صفحات نهایی خطا نمایش داده میشوند که برای پروژه‌های در حالت توسعه بسیار مفید میباشد.
در نسخه IIS7 تگ دیگری به نام httperrors هم نیز اضافه شده است؛ ولی برای استفاده در نسخه‌های پیشین و همچنین IIS express موجود در ویژوال استودیو از همان Custom error استفاده نمایید.
  
Trace
trace کردن در دات نت یکی از قابلیت‌های مهم در سیستم دیباگینگ به شمار میرود که در دو حالت (در سطح اپلیکیشن) و همچنین (در سطح صفحه) اجرا میشود. این اطلاعات شامل اطلاعات مهمی چون درخواست‌ها و پارامترها، توکن سشن‌ها و... میباشد که در انتهای صفحه یا در پنجره مخصوص به خود به کاربر نمایش میدهد. بدیهی است که برای انتشار نهایی برنامه، این گزینه باید غیرفعال باشد تا این اطلاعات دیده نشوند.
  
compilation debug 
با true شدن این گزینه در محیط اجرایی، مشکلات زیادی برای سیستم ASP.Net رخ میدهد که در زیر آن‌ها را بررسی میکنیم:
1- باعث افزایش حجم شاخه temp خواهد شد.
2- timeout شدن صفحات با مشکل مواجه خواهند شد و ممکن است این timeout شدن اصلا رخ ندهد.
3- Batch Compilation که در همین تگ قابلیت true و false شدن را دارد، به کل نادیده گرفته شده و طوری با آن رفتار خواهد شد همانند حالتیکه مقدارش به false تنظیم شده‌است. این گزینه این امکان را به ما میدهد در صورتیکه درخواست صفحه‌ای در یک پوشه‌ی خاص داده شد، بقیه صفحات در آن محل نیز پردازش شوند تا در صورت درخواست صفحات همسایه، سرعت بالاتری در لود آن داشته باشیم. البته ناگفته نماند در صورتیکه در همان لحظه زمانی، سرور بار سنگینی را داشته باشد، این فرایند کنسل خواهد شد.
4- همه کتابخانه‌های جاوااسکرپیتی و فایلهای استاتیکی که از طریق فایل  axd قابل دسترس هستند، قابلیت کش شدن را از دست داده و سرعت کندی خواهند داشت. همچنین در صورتیکه این گزینه با false مقداردهی شود، امکان فشرده سازی نیز اضافه خواهد شد.
5- واضح است که با فعال سازی این گزینه، امکان دیباگینگ فعال شده و همه موارد را برای دیباگر مهیا میکند تا بتواند تا حد ممکن، همه مباحث مانیتور شوند و این مورد بر کارآیی نهایی تاثیرگذار خواهد بود.
مطالب
گزینه "مرا به خاطر بسپار" درست کار نمی‌کند

حالت forms authentication در ASP.Net ، امکان تعریف کوکی‌هایی ماندگار را نیز جهت ورود خودکار کاربران در دفعات بعدی بازدید آن‌ها فراهم می‌کند. اما زمان منقضی شدن این کوکی‌های ماندگار در ASP.Net 1.1 و ASP.Net 2.0 به بعد کاملا با هم متفاوت بوده و اگر برنامه نویس از این تغییر حاصل شده مطلع نباشد ممکن است بارها و بارها برنامه را آزمایش کند اما نتیجه‌ای نگیرد.
مدت زمان منقضی شدن کوکی‌های ماندگار forms authentication در ASP.Net 1.1 به صورت زیر است (بود):
زمان منقضی شدن کوکی سشن = زمان جاری + زمان منقضی شدن سشن کاربر
زمان منقضی شدن کوکی ماندگار (persistent) = زمان جاری + 50 سال

این عدد 50 سال بسیار غیرمنطقی بوده و در ASP.Net 2.0 به بعد به صورت زیر اصلاح شده است:
زمان منقضی شدن کوکی سشن = زمان جاری + زمان منقضی شدن سشن کاربر
زمان منقضی شدن کوکی ماندگار (persistent) = زمان جاری + زمان منقضی شدن سشن کاربر (پیش فرض آن 30 دقیقه است)

و جهت بیشتر کردن طول عمر این ماندگاری باید زمان مورد نظر را در وب کانفیگ به صورت زیر اعمال کرد:

<authentication mode="Forms">
<forms

name="MyCookieName"
slidingExpiration="true"
timeout="43200"
/>
</authentication>
مطابق زمان تنظیم شده فوق که بر حسب دقیقه است، این کوکی به مدت یک ماه ماندگاری پیدا می‌کند در غیر اینصورت اعمال گزینه "مرا به خاطر بسپار" مطابق نظر شما کار نخواهد کرد و همانند ASP.Net 1.1 به صورت پیش فرض به 50 سال تنظیم نمی‌شود.

همچنین نکته‌ی مهم دیگری را که باید رعایت کرد، name ایی است که در این فایل config عنوان می‌‌کنید (در قسمت تنظیمات form authentication). اگر بر روی یک وب سرور، چندین برنامه وب ASP.Net را در حال اجرا دارید، باید برای هر کدام از این‌ها نامی جداگانه و منحصربفرد انتخاب کنید، در غیراینصورت تداخل رخ داده و باز هم گزینه مرا به خاطر بسپار شما کار نخواهد کرد.

کار slidingExpiration که در اینجا تنظیم شده است نیز به صورت زیر می‌باشد:
اگر لاگین موفقیت آمیزی ساعت 5 عصر صورت گیرد و timeout شما به عدد 10 تنظیم شده باشد، این لاگین به صورت خودکار در 5:10‌ منقضی خواهد شد. اما اگر در این حین در ساعت 5:05 ، کاربر یکی از صفحات سایت شما را مرور کند، زمان منقضی شدن کوکی ذکر شده به 5:15 تنظیم خواهد شد. (مفهوم تنظیم slidingExpiration)
لازم به ذکر است که اگر کاربر پیش از نصف زمان منقضی شدن کوکی (مثلا در 5:04)، یکی از صفحات را مرور کند، تغییری در این زمان نهایی منقضی شدن رخ نخواهد داد.

مطالب
آموزش Xamarin Forms - قسمت اول - نصب و راه اندازی اولین پروژه زمارین

در  مقاله قبلی ، درباره دلایل استفاده از Xamarin ، کمی صحبت کردیم. حال وقت آن رسیده که به سراغ نصب و راه اندازی اولین پروژه زمارین برویم.

اگر شما از Visual Studio 2015  به بعد استفاده کنید، موقع نصب قادر خواهید بود که با انتخاب گزینه Mobile Development و انتخاب Xamarin ، آن را نصب و همچنین تمامی فایل‌های مربوط به آن را دریافت کنید. در نظر داشته باشید که در طول این پروسه شما باید از ف.یل.تر شکن استفاده کنید، چرا که بعضی از فایل‌ها مانند Android Sdk بر روی سرور گوگل قرار دارد و گوگل آپی‌های ایران را برای برنامه نویسان فیلتر کرده است (البته اگر بسته‌ی کامل VS 2017 را دریافت کرده باشید، تمام این پیش نیازها، به همراه این بسته‌ی 21~ گیگابایتی موجود است و این مشکلات را نخواهید داشت). 

حال اگر در حال حاضر Visual Studio را بر روی سیستم خود نصب دارید و زمارین را نصب نکرده اید میتوانید از طریق خود سایت زمارین اقدام به دانلود آن بکنید. در نظر داشته باشید، وقتیکه فایل نصبی را از سایت دریافت میکنید، برنامه شروع به نصب خودکار زمارین و تمامی موارد مورد نیاز خود میکند که در این مورد هم به ف.یل.تر شکن نیاز دارید (منهای بسته‌ی کامل VS 2017 که پیشتر عنوان شد). همانطور که بالا گفته شد فایل هایی مانند Android Sdk را نمیتوان از آی پی ایران دانلود کرد (مگر اینکه از سایت‌های واسط استفاده کنید).

پس از موافقت با حقوق کپی رایت زمارین، سیستم شما را جستجو کرده و تمامی موارد مورد نیاز را که نیاز به نصب دارند، به شما نشان داده و نصب خواهد کرد.



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


اگر تمامی فایل‌های مورد نظر را دانلود کرده باشید، قادر خواهید بود اولین پروژه‌ی خود را شروع کنید. قبل از اینکه کار با زمارین را شروع کنیم، اجازه دهید از اینکه ویژوال استودیو تمامی فایل‌های نصب شده را تشخیص داده یا خیر، مطمئن شویم. ویژوال استودیوی خود را باز کرده و از منوی Tools، گزینه‌ی Options را انتخاب و بعد از باز شدن صفحه مورد نظر، در انتهای لیست، گزینه Xamarin را انتخاب کنید.

 


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

نکته : در نظر داشته باشید فایل‌های زیر برای اجرای برنامه بر روی اندروید میباشند و اگر شما تمایلی به اجرای نرم افزار خود را بر روی اندروید ندارید، میتوانید از آنها صرف نظر کنید.


در این مرحله میخواهیم اولین برنامه زمارین خود را شروع کنیم. همانطور که در مقاله قبلی  توضیح داده شد، شما میتوانید از xamarin forms و یا xamarin native استفاده کنید. Xamarin forms ساختاری برای code sharing میباشد که توسط شرکت زمارین توسعه داده شده‌است. به این ترتیب شما قادر خواهید بود که با استفاده از Xamarin Forms با نوشتن کمترین کد، نرم افزار خود را بر روی پلتفرم‌های پشتیبانی شده‌ی توسط زمارین اجرا کنید. استفاده از Xamarin Forms برای یک پروژه‌ی تجاری بسیار مناسب میباشد؛ اما در برخی موارد شما باید از Xamarin Native هم استفاده نمایید که در این صورت هم زمارین دست شما را نخواهد بست و قادر خواهید بود که به صورت ترکیبی از Xamarin Forms و Xamarin Native از آن استفاده نمایید.


حال به سراغ ساخت اولین پروژه زمارین برویم. در ابتدا برای ایجاد یک پروژه، از منوی File گزینه New و سپس گزینه Project را انتخاب کنید. در پنجره باز شده از سمت چپ گزینه C# را انتخاب و از زیر منوی Cross Platform گزینه Cross Platform App را انتخاب کنید.


پس از تایید با صفحه زیر مواجه خواهید شد.



در این قسمت همانطورکه مشاهده میکنید میتوانید از دو نوع  قالب استفاده کنید و همانطور که از نام آنها مشخص است، Master Detail دو پروژه خواهد ساخت که میتوانید از آن برای سناریو‌های خاص استفاده کنید. در قسمت پایین، UI Technology مشخص کننده‌ی شیوه پیاده سازی ظاهر برنامه است. زمارین فرم برای پیاده سازی ظاهر برنامه از Xaml استفاده میکند و شما میتوانید از طریق آن ظاهر تمامی پلت فرم‌ها را پیاده کنید. همچنین قادر خواهید بود بجای استفاده از Xaml، از زبان‌های مخصوص هر پلتفرم مانند Xml برای اندروید استفاده کرده و ظاهر نرم افزار خود را با استفاده از آن پیاده کنید.


زمارین فرم برای Code Sharing از دو روش استفاده میکند.

Shared Project

مزایا:

· شما به تمامی قسمت‌های یک پلتفرم دسترسی دارید.

· قادر خواهید بود کدهایی مخصوص به هر پلتفرم را بنویسید.

· میتوانید با استفاده از Conditional Compilation، بر اساس نوع پلتفرم، شروطی را اعمال نمایید.

معایب:

· شما با این روش نمیتوانید DLL ایی را تولید کنید و از آن در پروژه‌های دیگر استفاده نمایید.

· نوشتن Unit Testing نسبت به روش Portable پیچیده‌تر است.


Portable Class Library

مزایا:

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

· نوشتن Unit Test به سادگی امکان پذیر است.

معایب:

· در این روش شما نمیتوانید از کد‌های مخصوص به هر پلتفرم ( Platform-Specific ) استفاده کنید (البته با استفاده از Dependency Injection امکان پذیر است). 

· فقط قادر خواهید بود که از زیر مجموعه .Net استفاده نمایید.


در ادامه پس از انتخاب Xamarin Forms و Shared Project، بر روی Ok کلیک کنید. همانطور که میبینید ویژوال استودیو شروع به ساخت پروژه‌های برنامه میکند. اگر تمامی Sdk ‌های مورد نیاز را نصب کرده باشید، ویژوال استدیو 5 پروژه را برای شما میسازد (در نظر داشته باشید که اگر SDK مربوط به Universal Windows Platform را هم نصب کرده باشید، پروژه‌ی مربوط به آن را نیز خواهید دید).



اولین پروژه، پروژه Shared است که کد‌های برنامه در این پروژه نوشته خواهد شد.

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

در زمارین برنامه‌ها از فایلی به نام App اجرا میشوند. این فایل علاوه بر دسترسی به Life Cycle اپلیکیشن، وظیفه‌ی دیگر آن مشخص کردن اولین صفحه‌ی برنامه نیز میباشد. این فایل درون پروژه Shared  قرار دارد.



همانطور که مشاهده میکنید پس از باز کردن فایل App، در متد سازنده آن صفحه اصلی، به صفحه‌ای به نام MainPage که یک فایل Xaml میباشد، تنظیم شده‌است. پس از باز کردن فایل MainPage با کدهای زیر مواجه میشویم. 

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:PreviewerTest"
             x:Class="PreviewerTest.MainPage">

<Label Text="Welcome to Xamarin Forms!" 
           VerticalOptions="Center" 
           HorizontalOptions="Center" />
</ContentPage>


که مشخص کننده یک لیبل با متن Welcome to Xamarin Forms! میباشد. پس از اجرای برنامه میتوانیم کد اجرا شده را مشاهده کنیم. 

مطالب
نکاتی توصیه ای برای برنامه نویسی اندروید : قسمت دوم
در ادامه‌ی قسمت اول، ده مورد دیگر از نکات کاربردی را بیان می‌کنیم.

  یازده. در جاوا رویدادها با استفاده از اینترفیس‌ها پیاده سازی می‌شوند. برای نامگذاری یک رویداد، قاعده آن در جاوا بدین شکل است که نام‌ها به صورت (+ ) Camel نوشته شده و آخرین عبارت هم Listener باشد و نیازی هم به حرف I در نامگذاری اینترفیس نیست؛ چون همه می‌دانند که این Listener آخری یعنی رویدادی که با اینترفیس پیاده سازی شده است و استفاده از I بی معنی است. هر چند بر خلاف دات نت، در اینجا استفاده از قاعده I چندان متداول نیست.
 public interface CopyFileListener
    {
        void PublishProgress(long fileSize,long copiedSize);
    }

دوازده. گوگل اینترفیس‌هایی را که برای رویدادها میسازد، داخل کلاس اصلی تعریف میکند. پس بهتر هست که شما هم همین روند را ادامه بدید و از این قاعده خارج نشوید. اگر خوب دقت کرده باشید، در برنامه نویسی اندروید تمام اینترفیس‌ها داخل کلاس اصلی هستند:
 textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                
            }
        });
در کد بالا رویداد OnclickListener در خود کلاس View تعریف شده است. پس ما هم بهتر هست همین کار را بکنیم:
public class MemoryWare {

    public interface CopyFileListener
    {
        void PublishProgress(long fileSize,long copiedSize);
    }
....
}
یک نکته دیگر اینکه موقعی که یک رویداد را به یک پراپرتی set انتساب می‌دهیم، رسم این است که نام آن پراپرتی با عبارت SetOn آغاز شود و با نام اینترفیس پایان یابد:
SetOnClickListener
البته اگر کلاس شما لیستی از رویدادها را درست میکند بهتر است از عبارت Add به جای SetOn استفاده کنید و برای آن یک Remove هم قرار دهید. نمونه آن را می‌توانید در کد زیر ببینید:
 editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

سیزده
. آداپتورها و آداپتور ویوها (چون لیست) قسمت مهمی از برنامه‌های اندرویدی به شمار می‌آیند؛ تا حدی که در بیشتر برنامه‌های ساده هم حضور پررنگی دارند. ولی برای استفاده از این آداپتورها باید بدانید که نحوه کار آن‌ها چگونه است. بسیاری از کاربران در این قسمت اشتباهات زیادی می‌کنند. اگر در stackOverflow هم در اینباره نگاه کنید، با حجم انبوهی از سوالات روبرو می‌شوید و فقط به خاطر اینکه نحوه کارکرد آن را نمی‌دانند، به مشکل برخورده‌اند.
کلاس BaseAdapter اصلی‌ترین کلاس آداپتور هاست که بقیه از آن مشتق شده‌اند و معروفترین مشتقات آن، کلاس‌های CursorAdapter و ArrayAdapter هستند که امکانات بیس آداپتور را افزایش داده‌اند.به عنوان مثال در کد پایین از ArrayAdapter استفاده شده است.


نحوه کار یک آداپتور بدین صورت است که متدی را به نام GetView با قابلیت override دارد که با هر تعداد آیتم موجود صدا زده می‌شود. ولی اگر تصور کنیم فقط چند صدهزار آیتم هم داشته باشیم، آیا واقعا اجرا می‌شود؟ جواب این سوال این است که با هر بار اسکرولی که شما میکنید آیتم‌های بعدی ایجاد می‌شوند ولی باز این سوال پیش می‌آید که هر آیتم برای خود جداگانه تشکیل می‌شود؟ مطمئنا جواب خیر است. آداپتورها از سیستمی به نام ViewRecycler برای کش کردن آیتم‌های ایجاد شده استفاده می‌کنند و با هر اسکرولی که انجام می‌شود آیتم‌های بعدی از روی آیتم‌های قبلی که قبلا از صفحه خارج شده‌اند، ساخته می‌شوند و آیتم‌های کش شده قبلی را با پارامتری با نام convertView به دست شما می‌رساند.
کد زیر را ببینید:
  @Override
    public View getView(int position, View rowView, ViewGroup parent) {

        ViewHolder viewHolder=null;
        if(rowView==null)
        {
            // 1. Create inflater
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            // 2. Get rowView from inflater
            rowView = inflater.inflate(R.layout.row_bank_group_list, parent, false);
            viewHolder=new ViewHolder();
            viewHolder.txtGroupName=(TextView) rowView.findViewById(R.id.text_groupName);
            rowView.setTag(viewHolder);
        }
        else
        {
            viewHolder=(ViewHolder)rowView.getTag();
        }
        viewHolder.txtGroupName.setText(getItem(position).getName());
        viewHolder.txtGroupName.setTypeface(new FontSystem().get_General_Font(context));
        viewHolder.txtGroupName.setTextColor(context.getResources().getColor(R.color.black));

        return rowView;
    }
کد بالا ابتدا بررسی میکند که آیا convertView نال است یا خیر. اگر نال بود به این معنا است که کش برای شما چیزی نداشته است و باید آیتم جدیدی را بسازید. پس اشیاء موجود در آن را در حافظه می‌آورید و مقداردهی می‌کنید. ولی اگر برابر نال نباشد، یعنی کش حاوی یک سری آیتم است که قبلا ایجاد شده‌اند. پس نیاز به inflate کردن مجدد ندارد و میتوانید  همان را مستقیما مورد استفاده قرار دهید و با مقادیر جدید آن را ست کنید.
کلاس داخلی ViewHolder هم یک الگو برای عدم بررسی Viewهای داخل آن است که نیازی به یافتن و تبدیل مجدد آن‌ها نداشته باشید. در این روش شیء، داخل خصوصیت tag آیتم قرار گرفته است و وقتی از کش برداشته شود، خاصیت تگ آن را می‌خوانیم و مستقیما مورد استفاده قرار می‌دهیم. در این حالت شما بهترین استفاده را از پردازش‌ها و حافظه، می‌کنید.

چهارده. یکی از کارهایی را که قبل از کار کردن در یک مسیر فیزیکی باید انجام دهید این است که مطمئن باشید اجازه نوشتن در آن ناحیه را دارید یا خیر. در غیر اینصورت برنامه شما با خطای FC روبرو می‌شود و اجرای آن خاتمه می‌یابد. به همین دلیل اکثر برنامه نویسان از متد CanWrite در کلاس File استفاده می‌کنند. ولی در هنگام استفاده از این متد باید دقت داشته باشید که کلاس File فقط باید حاوی مسیر باشد و اسمی از فایل مربوطه در آن نباشد. دلیل هم آن است که این احتمال می‌رود اگر فایلی هم وجود نداشته باشد، مقدار false را به شما برگرداند. مثال زیر قرار است فایلی را در کارت حافظه بنویسید، ولی بررسی اجازه نوشتن در مسیر، اشتباه است:
File file=new File(sdcardPath,fileName);

if(file.CanWrite())
{
  .....
}
کد بالا را به طور صحیح بازنویسی می‌کنیم:
File file=new File(sdcardPath);

if(file.CanWrite())
{
file=new File(sdcardPath,filePath);
  .....
}
اگر هنگام تست این کد مشکلی نداشتید، دلیل بر صحت کد نیست. بلکه بنابر تجربه شخصی من، زمانی این مشکل پیش آمده بود که روی چند گوشی تست شده و بعدها مشکل در گوشی پیش آمده بود که هم مدل و دقیقا مشابه یکی از گوشی‌های تستی بود.

پانزده. کارت حافظه خارجی: همه برنامه نویسان اندروید حداقل یکبار از کد زیر استفاده کرده اند:
Environment.getExternalStorageDirectory()
بررسی‌ها در استک اورفلو نشان می‌دهد که برنامه نویسان، گزارش عملکرد اشتباهی را از این متد دارند. ولی حقیقت این است که این متد به هیچ عنوان مقدار اشتباهی را بر نمی‌گرداند. بلکه منطق آن متفاوت از چیزی است که شما فکر می‌کنید. وقتی ما صحبت از حافظه خارجی برای یک گوشی میکنیم، منظور همان کارت حافظه‌ای است که به طور جداگانه داخل گوشی قرار داده‌ایم و انتظار داریم متد بالا آدرس و مدخل همین کارت را برای ما فراهم کند. ولی در کمال تعجب می‌بینیم که آدرس حافظه داخلی برگردانده می‌شود. پس باید ببینیم اندروید از  آن چه انتظاری دارد؟
هر برنامه‌ای که در اندروید نصب می‌شود در مسیر
/Data/Data
یک دایرکتوری با نام خود دارد مثل:
/Data/Data/Info.Dotnettips.MyApp
این دایرکتوری تنها متعلق به این برنامه بوده و کسی جز Root به آن دسترسی ندارد. اندروید این دایرکتوری را به عنوان حافظه داخلی در نظر میگیرد که برای کار با آن نیاز به هیچ آدرس دهی نیست. ولی در کنار این دایرکتوری حافظه داخلی خود گوشی که در آن انبوه فایل‌های خود را ذخیره می‌کنید هم هست که اندروید آن را حافظه خارجی می‌پندارد. حال آن حافظه‌ای را که شما جداگانه به صورت یک کارت یا USB OTG متصل میکنید، به عنوان حافظه خارجی در نظر نمیگیرد. در صورتی که شما چنین انتظاری را دارید، برای حل این مشکل بهتر است از کدهای موجود مثل کد زیر استفاده کنید:
    /**
     * it will returns sd path for you
     *  <p>
     *  <b>Required Permission: </b>android.permission.READ_EXTERNAL_STORAGE<br/>
     * </p>
     * @return
     */
    public  List<String> GetExternalMounts() {
        final List<String> out = new ArrayList<>();
        String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
        String s = "";
        try {
            final Process process = new ProcessBuilder().command("mount")
                    .redirectErrorStream(true).start();
            process.waitFor();
            final InputStream is = process.getInputStream();
            final byte[] buffer = new byte[1024];
            while (is.read(buffer) != -1) {
                s = s + new String(buffer);
            }
            is.close();
        } catch (final Exception e) {
            e.printStackTrace();
        }

        // parse output
        final String[] lines = s.split("\n");
        for (String line : lines) {
            if (!line.toLowerCase(Locale.US).contains("asec")) {
                if (line.matches(reg)) {
                    String[] parts = line.split(" ");
                    for (String part : parts) {
                        if (part.startsWith("/"))
                            if (!part.toLowerCase(Locale.US).contains("vold"))
                                if(new File(part).canWrite())
                                    out.add(part);
                    }
                }
            }
        }
        return out;
    }

شانزده.
یکی از روش‌های انتقال اطلاعات بین اکتیویتی‌ها مختلف استفاده از Extras هاست که شما با تعیین یک نام یا کلید، اطلاعات مربوطه را ارسال و توسط همان کلید؛ اطلاعات را در اکتیویتی مقصد دریافت میکنید:
notesIntent.putExtra("PartyId", PartyId);
startActivity(notesIntent);
و در مقصد:
PartyId=getIntent().getLongExtra("PartyId",0);
در این حالت بهتر است با این رشته‌ها نیز همانند مورد شماره دو در قسمت اول رفتار شود تا نیازی به نوشتن و تکرار این نام‌ها نباشد. ولی با یک نگاه به استانداردهای نوشته شده در خود اندروید و بسیاری از کتابخانه‌های ثالث در می‌یابیم که بهترین روش این است که این کلید‌ها را به صورت متغیرهای ایستا در خود اکتیویتی ذخیره کنیم؛ در این حالت هر کلید در جایگاه واقعی خودش قرار گرفته است. نمونه‌ای از این استفاده را می‌توانید در کتابخانه FilePicker مشاهده کنید:
i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false);
i.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, false);
i.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_FILE);

هفده.
قواعد نامگذاری: برای نامگذاری متغیرها از قانون CamelCase استفاده میکنیم. ولی برای حالات زیر از روش‌های دیگر استفاده می‌شود:
  • برای ثابت‌ها از حروف بزرگ و _ استفاده کنید.
  • برای متغیرهای خصوصی از حرف m در ابتدای نام متغیر استفاده کنید.
  • برای متغیرهای استاتیک از حرف s در ابتدای نام متغیر استفاده کنید.
نمونه ای از این نامگذاری که توسط مستندات گوگل سفارش شده است:
public class MyClass {
    public static final int SOME_CONSTANT = 42;
    public int publicField;
    private static MyClass sSingleton;
    int mPackagePrivate;
    private int mPrivate;
    protected int mProtected;
}

هجده:
قاعده نظم و ترتیب در import‌ها توسط مستندات گوگل بدین شکل تعریف شده است:
  1. نام پکیج‌های ارائه شده توسط گوگل
  2. نام پکیج‌های ثالث
  3. نام پکیج‌های موجود در java و javax
  4. پکیج‌های موجود در پکیج اصلی
البته رعایت این قاعده کمی سخت و عموما بدون اجراست ولی نگران نباشید. از آنجایی که ادیتور از طرف jet brains ارائه شده‌است و عمل import به طور خودکار صورت میگیرد و با ابزارهای دیگری که در دل این ادیتور قرار گرفته است، این عمل به طور خودکار انجام می‌گیرد.

نوزدهم. مرتب سازی متدهای دسترسی یک کلاس: بسیار خوب است که همیشه کدهای ما نظم خاصی را داشته باشد تا پیگیری‌های شخصی و تیمی در آن راحت‌تر صورت بگیرد. برای مثال در یک کلاس ابتدا متدهای public و سپس private قرار گیرند و الی آخر.
الگوی عمومی که برای کار با جاوا صورت گرفته است به شکل زیر می‌باشد:
public, protected, private,abstract, static, transient, volatile, synchronized, final, native.
البته این متدهای دسترسی بسته به فیلد بودن و متد بودن نیز تغییر میکند. به عنوان مثال ابتدا فیلدها در نظر گرفته می‌شوند و سپس متدها و ...
ادیتور intelij شامل تنظمیاتی برای مرتب سازی کدهاست که در این مورد بسیار سودمند است. با طی کردن مسیر زیر می‌توانید برای آن ترتیب اینگونه موارد را مشخص کنید.
Settings>Editor>Code Style>Arrangement
در اینجا شما امکان تعاریف این ترتیب‌ها را دارید. البته بهتر هست در حالت پیش فرض باشد تا حالتی عمومی بین افراد مختلف برقرار باشد.

در تصویر بالا متدها به ترتیب متدهای دستری بین بلوک‌های کامنت method start و method end قرار گرفته اند.

 همچنین شامل گزینه‌های دیگری نیز میباشد که به نظرم فعال کردنشان بسیار خوب است. گزینه keep overridden methods together به شما کمک می‌کند تا متدهایی را که رونویسی می‌شوند، در کنار یکدیگر قرار بگیرند که برای کلاس‌های اندرویدی مثل اکتیویتی‌ها و فرگمنت‌ها و ... بسیار خوب است. گزینه مفید دیگر Keep dependent methods together است که در دو حالت عمقی یا خطی متدهای وابسته (متدهایی که متدهای دیگر را در آن کلاس صدا میزنند) در کنار یکدیگر قرار میدهد و مابقی گزینه‌ها، که بسیار سودمند هست. به هر حال هر قاعده‌ای را که برای خود انتخاب میکنید اگر در حالت پیش فرض نیست بهتر است در مستندات پروژه ذکر شود تا افراد دیگر سریعتر به موضوع پی ببرند.

قسمت بیستم. این مورد برای افراد تازه کار می‌باشد که تازه اندروید استادیو را باز کرده‌اند و مشغول کدنویسی می‌باشند. یکی از مواردی که در همان مرحله اول به آن برمیخورید این است که intellisense  ادیتور به بزرگی و کوچکی حروف حساس است و تنها با حرف اول سازگاری دارد. برای تغییر این مسئله باید مسیر زیر را طی کنید:
Settings>Editor>Completion>Case-sensitive Completion>None
حالا با تایپ هر کلمه، دستورات و آبجکت‌هایی را که شامل آن کلمات باشند، به شما نمایش داده خواهند شد.

نظرات مطالب
نحوه ارتقاء برنامه‌های موجود MVC3 به MVC4
قبل از اینکه جوابتونو ببینم تماس گرفتم به سرویس دهنده‌ی هاست که مشکلم کامل حل شد :ایکس ... مشکل همونی هست که شما میگین ولی رو وب سایت پنل خودشون رو asp.net 2 تنظیم بود که درسش کردم. 
الان با این شرایط که من میبینم و اونا هم ساپورت mvc 4 ندارند پس نیازی به روی هاست بودن mvc 4 نیست چون پروژم کاملا داره کار میکنه :دی