نظرات مطالب
Globalization در ASP.NET MVC - قسمت ششم
برای طراحی یک سامانه مدیرت محتوا با کلی ماژول فکر می‌کنم حرفم منطقی باشه مهندس، در ضمن همونجوری که مهندس یوسف نژاد فرمودن اطلاعات در بازیابی اولیه کش میشه و تا ری ستارت شدن سایت در حافظه می‌مونه، فکر می‌کنم چندان تاثیری بروی کارایی داشته باشه با توجه به فرضیات، فرض کن من 10000 عنوان دارم، 30 تا زبان دارم در این صورت توی یک جدول زبان انگلیسی (en-کالچر انگلیسی) 10000 بار تکرار میشه علاوه بر اون عنوان مثلا "نام کاربری" به ازای 30 زبان 30 بار تکرار میشه زیادم حرف من غیر منظقی نیست و الا حرف شما درسته بله join سرعت پایین میاره اما ما که قرار نیست زیادی دسترسی به این جداول داشته باشیم.
"پس از اولین درخواست برای هر منبع، نمونه تولیدشده از پرووایدر مربوطه در حافظه سرور کش خواهد شد." سخن مهندس یوسف نژاد
مطالب
توسعه برنامه‌های Cross Platform با Xamarin Forms & Bit Framework - قسمت شانزدهم
در این قسمت می‌خواهیم به بحث Style دهی و Font‌ها در Xamarin Forms بپردازیم. در XF به دو روش می‌توان Style اعمال کرد؛ یکی با CSS و دیگری با Xaml. از هر روشی که استفاده کنیم، Styleها درون Resource‌ها قرار می‌گیرند. Resource، یک Dictionary است که درون آن هر چیزی می‌توان قرار داد؛ یک string یا Style یا عدد و ...
فایل App.xaml و همچنین تک تک صفحات، دارای Resources هستند که اگر چیزی درون App.xaml Resources قرار بگیرد، در کل برنامه می‌توان از آن استفاده کرد. برای مثال در صورت قرار دادن یک Style در App Resources، آن Style بر روی کل برنامه قابلیت اعمال پیدا می‌کند. همچنین اگر چیزی درون Resources یک صفحه قرار بگیرد، فقط برای کنترل‌های درون آن صفحه در دسترس است و ...
در روش Style دهی به سبک Xaml، می‌توانید از تمامی امکاناتی که تا اینجا یاد گرفته‌اید استفاده کنید؛ برای مثال Triggers و Binding و ... . هر Style یک Target Type دارد، اگر Style ای Target Type اش Label باشد، برای تمامی Property‌های Label می‌تواند تعیین تکلیف کند:
<Style TargetType="Label">
    <Setter Property="FontFamily" Value="Some font..." />
</Style>
هر Label مقدار FontFamily یا سایر Property‌های خودش را به شکل زیر حساب می‌کند:
1- اگر بر روی یک Label، صراحتا FontFamily مقدار دهی شود، آن مقدار معتبر در نظر گرفته می‌شود.
2- اگر در Resource‌های آن صفحه ای که Label درون آن قرار دارد، Style برای Label تعریف شود و در آن Style به FontFamily مقداری تخصیص داده شده باشد، آن مقدار ملاک قرار می‌گیرد.
3- اگر نه بر روی خود Label و نه در Resourceهای صفحه ای که Label در آن قرار دارد، مقدار FontFamily مشخص نشود، آنگاه بررسی می‌شود که آیا Style ای در App.xaml برای Label وجود دارد که به FontFamily مقداری داده باشد یا نه، که اگر وجود داشته باشد، آن عدد ملاک است.
4- در نهایت اگر هیچ جایی از FontFamily صحبتی نشده باشد، مقدار پیش فرض ارائه شده توسط تیم Xamarin Forms ملاک قرار می‌گیرد.

البته این آموزش همه جزئیات را شامل نمی‌شود تا از پیچیده شدن بحث جلوگیری کند و با همین مقدار از یادگیری نیز می‌توانید به خوبی کار خود را پیش ببرید.
حال اگر بخواهیم تمامی صفحات برنامه، Background آبی داشته باشند، می‌توان در App.xaml برای ContentPageها یک Style نوشت که BackgroundColor را آبی تعیین کرده باشد:
<Style TargetType="ContentPage" ApplyToDerivedTypes="True" >
    <Setter Property="BackgroundColor" Value="Blue" />
</Style>  
اگر دقت کنید، ApplyToDerivedTypes نیز مقدار True گرفته است. علت این است که صفحه لاگین که برای مثال قصد آبی کردن آن را به همراه تمامی صفحات دیگر داریم، از جنس ContentType نیست، بلکه از آن ارث بری کرده‌است. همچنین PopupPage‌ها نیز از ContentPage ارث بری کرده‌اند. با ApplyToDerivedTypes ما این Style را نه تنها بر روی ContentPage که بر روی کلاس‌هایی که از آن ارث بری کرده‌اند نیز اعمال می‌کنیم. صد البته که در پروژه ما خود ContentPage اصلا جایی مستقیما استفاده نشده‌است و تمامی صفحات ما، در واقع ارث بری ای از ContentPage محسوب می‌شوند. البته در مثال Label، ارث بری ای در کار نیست و همیشه مستقیما از Label استفاده می‌کنیم، نه اینکه از آن ارث بری کنیم.
حال ممکن است بخواهیم Style ای تعریف کنیم به نام Danger Button که نه کل دکمه‌های برنامه که چندتایی در صفحات مختلف می‌خواهند از آن استفاده کنند. اگر برای Button یک Style نوشته شود، تمامی Buttonها آن را خودکار می‌گیرند، پس راه حل چیست؟ راه حل این است که به Style ای که تعریف کرده‌ایم، یک x:Key دهیم. اگر Style ای Key داشته باشد، باید موقع استفاده در هر Button، نام آن Key ذکر شود.
<Style x:Key="DangerButton" TargetType="Button">
    <Setter Property="BackgroundColor" Value="Red" />
    <Setter Property="FontAttributes" Value="Bold" />
</Style>  
سپس موقع استفاده داریم:
<Button Style="{StaticResource DangerButton}" />
وقتی از StaticResource استفاده می‌کنیم، در Resourceهای صفحه‌ای که Button در آن قرار دارد و یا در App.xaml دنبال یک Style با x:Key برابر با DangerButton می‌گردد.
برای استفاده از Binding/Trigger در Styleها مثالی را داریم که متن تمامی Entryها به صورت Bold می‌شود، وقتی که IsFocused آنها True است!
<Style TargetType="Entry">
    <Style.Triggers>
        <Trigger TargetType="Entry" Property="IsFocused" Value="True">
            <Setter Property="FontAttributes" Value="Bold" />
        </Trigger>
    </Style.Triggers>
</Style>
برای Style دهی به شکل CSS نیز مثال زیر را داریم که متن تمامی buttonها را bold می‌کند:
<StyleSheet>
<![CDATA[
    button {
        font-style: bold;
    }
]]>
</StyleSheet>
می‌توان cssها را در فایل‌هایی با پسوند css نیز نوشت و به پروژه اضافه کرد. همچنین هر کنترل، دو ویژگی StyleId و class را دارد که بتوان به آن class / id داد تا در css به صورت . یا # استایل داد. مواردی چون stackpanel label به معنی label هایی که درون stack panel هستند و ... نیز پشتیبانی می‌شوند.
در رابطه با فونت نیز شما باید ابتدا فونت یا فونت‌های مربوطه را به هر سه پروژه Android/iOS/Windows اضافه کنید و سپس در App.xaml برای Font Family کنترل‌های مختلفی چون Label و ... از آن فونت استفاده کنید.
برای این مهم، ابتدا فایل‌های فونتی را انتخاب کرده (مثلا Open Sans) را به پروژه Windows/Android/iOS اضافه کنید: (سه فایل ما OpenSansItalic.ttf/OpenSansBold.ttf /OpenSansRegular.ttf هستند) 
در ویندوز آنها را در فولدر Assets/Fonts و در Android در فولدر Assets/Fonts و در iOS در فولدر Resources/Fonts کپی کنید. در iOS علاوه بر این کار، این‌ها را نیز به Key Value‌های فایل info.plist نیز اضافه کنید:
<key>UIAppFonts</key>
<array>
    <string>Fonts/OpenSansItalic.ttf</string>
    <string>Fonts/OpenSansRegular.ttf</string>
    <string>Fonts/OpenSansBold.ttf</string>
</array>  

سپس کدهای زیر را استفاده کنید:

<bitView:OnPlatform
    x:Key="OpenSansRegular"
    x:TypeArguments="x:String"
    Value="{OnPlatform Android='Fonts/OpenSansRegular.ttf#Open Sans',
                        iOS='OpenSans-Regular',
                        UWP='Assets/Fonts/OpenSansRegular.ttf#Open Sans'}" />

<!--  Italic مشابه کد بالا برای -->
<!--  Bold مشابه کد بالا برای -->

چون آدرس و نحوه نام دهی FontFamily در سه پلتفرم متفاوت است، با استفاده از OnPlatform، یک String می‌سازیم با x:Key برابر با OpenSansRegular که در هر پلتفرم مقدار خود را دارد. سپس از این نام برای مقدار دهی FontFamily در کنترل‌های Label/Entry/Button و ... در حالت‌های None/Italic/Bold استفاده می‌کنیم. برای مثال:

<Style TargetType="Label">
    <Style.Triggers>
        <Trigger TargetType="Label" Property="FontAttributes" Value="Bold">
            <Setter Property="FontFamily" Value="{StaticResource OpenSansBold}" />
        </Trigger>
        <Trigger TargetType="Label" Property="FontAttributes" Value="Italic">
            <Setter Property="FontFamily" Value="{StaticResource OpenSansItalic}" />
        </Trigger>
        <Trigger TargetType="Label" Property="FontAttributes" Value="None">
            <Setter Property="FontFamily" Value="{StaticResource OpenSansRegular}" />
        </Trigger>
    </Style.Triggers>
</Style>

این کد می‌گوید زمانیکه FontAttributes یک Label برابر با Bold است، از OpenSansBold برای FontFamily اش استفاده شود و همینطور برای Italic و None (یا همان Regular)

در قسمتی‌که داشتیم برای اندروید و ویندوز، مسیر فایل فونت را مشخص می‌کردیم، از مقدار OpenSansRegular.ttf#Open Sans استفاده کردیم که OpenSansRegular.ttf نام فیزیکی فایل و Open Sans نام خود فایل است که با دو بار کلیک کردن روی فایل آن در ویندوز از طریق برنامه Font ویندوز قابل مشاهده است:

همچنین برای اینکه این سه فایل، سه بار برای سه پلتفرم در سورس کنترلر کپی نشوند، از روش Add as link در Visual Studio بهره گرفته‌ایم و فایل فیزیکی فونت‌ها فقط در پروژه UWP وجود دارند. البته این به معنای این نیست که در Apk نهایی Android و ipa نهایی iOS این فایلها وجود نخواهند داشت؛ بلکه به خاطر ماهیت Add as link، انگار که این فایل‌ها در هر سه پروژه هستند و پشت صحنه کپی می‌شوند.

پاسخ به بازخورد‌های پروژه‌ها
مشکل در فوتر
با سلام دوباره
من از مارجین هم استفاده کردم اما کل صفحه رو مارجین داد و باز هم در صفحه اول سامری با فوتر من تداخل داشت اما در صفحات بعدی این مشکل وجود نداره
متشکرم از شما
نظرات مطالب
مدیریت سفارشی سطوح دسترسی کاربران در MVC
ممنون بابت مطلب مفیدی که در اختیار ما قرار دادید.
گفتید که مجوزها بعد از یک بار واکشی در کوکی ذخیره میشه، این به خاطر وجود مقدار true برای خصوصیت cacheRolesInCookie هست درسته؟ اما من یک RoleProvider سفارشی تهیه کردم که به صورت زیر اونو به وب کانفیگ اضافه کردم:
<roleManager cacheRolesInCookie="true" enabled="true" defaultProvider="CustomRoleProvider">
      <providers>
        <clear />
        <add name="CustomRoleProvider" 
             type="MvcApp.UserInterface.Models.CustomRoleProvider" 
             connectionStringName="MvcAppDb" 
             applicationName="/" />
      </providers>
</roleManager>
اما با مراجعه به کوکی‌های مروگر چیزی نمی‌بینم، در ضمن یک Break Point هم سر متد GetRolesForUserگذاشتم که هر وقت قصد دیدن یک اکشن برای یک Role رو مشخص دارم این متد اجرا میشه یعنی از کوکی نقش رو نمی‌خونه.
سوال بعدیم اینه که این نقش چطوری توی مرورگر کاربر ذخیره میشه؟ آیا رمز گزاری شده هست یا نه به صورت Plain Text ذخیره میشه؟ اگه رمزگزاری میشه با چه الگوریتمی این کار انجام میشه و آیا میشه اونو Decrypt کرد؟
با تشکر



نظرات مطالب
سیلورلایت 5 و تاریخ شمسی
آقای نصیری. آیا من که تا الان سمت سیلورلایت نرفتم با توجه به صحبت هایی که داره میشه مبنی بر اینکه به زودی سیلورلایت منسوخ میشه و اینکه خود مایکروسافت هم قصد داره بیشتر سرمایه ش رو بزاره رو HTML5 آیا کار درستیه که وقت بزارم برای یادگیری این تکنولوژی یا خیر ؟ ممنون میشم پاسخ بدید ؟
نظرات مطالب
شروع به کار با AngularJS 2.0 و TypeScript - قسمت هشتم - دریافت اطلاعات از سرور
این مسئله کش رو در یک محیط عملیاتی چطور میشه رفع کرد.
برای مثال یک سیستمی دارم که آن را تغییر میدهم ولی کاربران به دلیل مشکل کش به مشکل برخورد خواهند کرد.
نظرات مطالب
Best Practice ی برای تأیید اعتبار کردن کاربران در ASP.NET MVC 4
«بعد از داخل اون Redirect میشه» خودکار هست یا دستی؟ اگر خودکار هست، خوب طبیعی هست جایی که AllowAnonymous نداره (یعنی اکشن متد بعدی که به اون Redirect شده)، کاربر رو به صفحه لاگین هدایت کنه. Global Filters یعنی دقیقا همین. یعنی اعمال سراسری به همه جا، مگر اینکه با AllowAnonymous مستثنی شود.
نظرات نظرسنجی‌ها
با توجه به امکانات جدید Razor Components، آیا در آینده از SPA frameworks استفاده میکنید؟
ممنون از نظر خوبتون ولی یک نکته رو باید مطرح کنم در رابطه با پاسختون اینکه :
به نظرم مقایسه این با سیلورلایت کار درستی نباشه سیلورلایت پلاگین بود ولی این خودش داره از جاوااسکریپت استفاده میکنه و دلیلی نداره وقتی از این تکنولوژی استفاده کنیم کلا جاوا اسکریپت استفاده نشه میشه همچنان از ترکیبی از جاوااسکریپت و razor استفاده کرد.
هرچند سابقه ماکروسافت در مورد سیلورلایت خراب هست و شاید فکر کنیم این هم مثل اون میشه ولی فکر میکنم الان با کسب تجربه داره عمل میکنه و اون اتفاق نمیفته.
برای کارهای پیشرفته‌تر هم میشه بخشی از فریم ورک‌های spa رو همچنان استفاده کرد بدون routing و درگیری با api برای برنامه‌های متوسط و کوچک تر. به طور مثال vue در کنار این فریم ورک فکر میکنم خیلی میتونه خوب کار کنه.
نظرات مطالب
Url Routing در ASP.Net WebForms
این نوع routing خاص سمت کلاینت برنامه‌های تک صفحه‌ای وب را با استفاده از کتابخانه‌ای مانند path.js می‌شود انجام داد. مثال‌های آن‌را به همراه سورس صفحات آن بررسی کنید.
نمونه آن‌را در مطلب « پیاده سازی دکمه «بیشتر» یا «اسکرول نامحدود» به کمک jQuery در ASP.NET MVC  » (کامنت آخر آن) پیاده سازی شده می‌توانید مشاهده و دریافت کنید. از این قابلیت در سایت جاری در حال استفاده است. مثلا اگر به قسمت مطالب در بالای صفحه مراجعه کنید، چنین آدرسی قابل مشاهده است:
https://www.dntips.ir/postsarchive#/page/1/date/desc  
در پایین صفحه اگر دراپ داون‌های مرتب سازی را تغییر دهید، نام فیلد یا صعودی و نزولی بودن آدرس تغییر می‌کنند. شماره صفحه نیز با هر بار کلیک بر روی دکمه‌ی بیشتر یکی اضافه می‌شود. همچنین این آدرس‌ها را می‌شود ذخیره و عینا بازیابی کرد.
اشتراک‌ها
نکات افزایش پرفرمنس برای وبسایت

In this post, I'll talk about what the different things I've made on this website to improve the performance. Some of the optimizations are just some configuration flags to turn on, others require more changes in your code.

  • Enable HTTP/2
  • Enable TLS 1.3
  • Compress responses using Brotli or gzip
  • Add caching information
  • Optimize JavaScript / CSS files
  • Reduce the number of redirections
  • Optimize images
  • Move your servers near your visitors (GeoDNS, CDN)
  • Resource Hints: Prefetch resources
  • Remove unused resources / features
  • Minify HTML
  • Optimize JavaScript code
  • Automate almost everything! 
نکات افزایش پرفرمنس برای وبسایت