یکی از مفاهیم DATA SCIENCE که خیلیها با آن آشنا نیستند مفهوم دادههای مرتب یا TIDY DATA هست.. مثلا من چند وقت پیش درگیر یک پروژه تحت نظر یکی از شرکتهای بزرگ هلندی که بودجه چند ده میلیون دلاری و یک تیم اختصاصی DATA SCIENCE داشت بودم و این شرکت یک دیتاست برای تحلیل به من داد. وقتی من دیتاست را دیدم متوجه شدم که این دیتاست از استاندارد دادههای مرتب پیروی نمیکند و طبیعتا تمامی تحلیلهای قبلی آن شرکت دارای عیب و ایراد بود. جالبتر این بود که کسی در خصوص این مفهوم و این استاندارد نمیدانست و وقتی در خصوص این مساله به آنها گفتم خیلی حال کردند و خوشحال شدند! برای هممین تصمیم گرفتم که پستی در این خصوص بنویسم چون احتمالا خیلی از ماها هم از وجود این استاندارد خبر نداریم.
اگر میخواهید برای مثال از روش کوکی ذکر شده (در متد public IActionResult SetFaLanguage ابتدای بحث) استفاده نکنید، میتوان تامین کنندهی چهارمی را هم تدارک دید:
public class FaRequestCultureProvider : RequestCultureProvider { public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext) { return Task.FromResult(new ProviderCultureResult("fa-IR")); } }
public void Configure(IApplicationBuilder app) { var requestLocalizationOptions = new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture(new CultureInfo("fa-IR")), SupportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("fa-IR") }, SupportedUICultures = new[] { new CultureInfo("en-US"), new CultureInfo("fa-IR") } }; requestLocalizationOptions.RequestCultureProviders.Insert(0, new FaRequestCultureProvider()); app.UseRequestLocalization(requestLocalizationOptions);
معرفی ELMAH
عموما کاربران نمیتوانند گزارش خطای خوبی را ارائه بدهند و البته انتظاری هم از آنان نیست. تنها گزارشی که از یک کاربر دریافت میکنید این است: "برنامه کار نمیکنه!" و همین!
روشهای متعددی برای لاگ کردن خطاهای یک برنامه ASP.Net موجود است؛ چه خودتان آنها را توسعه دهید و یا از ASP.NET health monitoring استفاده کنید.
روش دیگری که این روزها در وبلاگهای متعددی در مورد آن مطلب منتشر میشود، استفاده از ELMAH است. (البته ELMAH به تازگی منتشر نشده ولی تا کیفیت محصولی به عموم ثابت شود مدتی زمان میبرد)
ELMAH یک ماژول رایگان و سورس باز لاگ کردن خطاهای مدیریت نشده برنامههای ASP.Net است. برای استفاده از این ماژول نیازی نیست تا تغییری در برنامه خود ایجاد کنید یا حتی آنرا کامپایل مجدد نمائید. یک فایل dll دارد به همراه کمی تغییر در web.config برنامه جهت معرفی آن و این تمام کاری است که برای برپایی آن لازم است صورت گیرد. این ماژول تمامی خطاهای مدیریت نشدهی برنامه شما را لاگ کرده (در حافظه سرور، در یک فایل xml ، در یک دیتابیس اس کیوال سرور یا اوراکل ، در یک دیتابیس اکسس و یا در یک دیتابیس اس کیوال لایت) و برای مرور آنها یک صفحهی وب سفارشی یا فیدی مخصوص را نیز در اختیار شما قرار میدهد. همچنین این قابلیت را هم دارد که به محض بروز خطایی یک ایمیل را نیز به شما ارسال نماید.
با توجه به اینکه این ماژول در Google code قرار گرفته احتمالا دسترسی به آن مشکل خواهد بود. سورس و فایلهای کامپایل شده آنرا از آدرسهای زیر نیز میتوان دریافت نمود:
نحوه استفاده از ELMAH :
برای استفاده از ELMAH دو کار را باید انجام دهید:
الف) کپی کردن فایل Elmah.dll در پوشه bin برنامه
ب) تنظیم وب کانفیگ برنامه
بهترین مرجع برای آشنایی با نحوه بکار گیری این ماژول، مراجعه به فایل web.config موجود در پوشه samples آن است. بر اساس این فایل نمونه:
- ابتدا باید configSections آن را به وب کانفیگ خود اضافه کنید.
- سپس تگ elmah باید اضافه شود. در این تگ موارد زیر مشخص میشوند:
الف) آیا خطاها توسط آدرس elmah.axd توسط کاربران راه دور قابل مشاهده شود یا خیر.
ب) خطاها کجا ذخیره شوند؟ موارد زیر پشتیبانی میشوند:
دیتابیسهای اس کیوال سرور ، اوراکل ، حافظه سرور، فایلهای xml ، دیتابیس SQLite ، دیتابیس اکسس و یا دیتابیسی از نوع VistaDB
ج) آیا خطاها ایمیل هم بشوند؟ اگر بلی، تگ مربوطه را تنظیم کنید.
د) آیا خطاها به اکانت twitter شما نیز ارسال شوند؟
- در ادامه تگ مربوط به معرفی این httpModules باید تنظیم شود.
- سپس httpHandlers ایی به نام elmah.axd که جهت مرور خطاها میتوان از آن استفاده نمود معرفی میگردد.
- از IIS7 استفاده میکنید؟ قسمت system.webServer را نیز باید اضافه نمائید.
- و در آخر نحوهی دسترسی به elmah.axd مشخص میشود. اگر اجازه دسترسی از راه دور را داده باشید، به این طریق میشود دسترسی را فقط به کاربران مجاز و تعیین اعتبار شده، اعطاء کرد و یا به نقشی مشخص مانند ادمین و غیره.
برای نمونه، اگر بخواهید از دیتابیس SQLite جهت ذخیره سازی خطاهای حاصل شده استفاده نمائید و نیز از ارسال ایمیل صرفنظر کنید، وب کانفیگ برنامه شما باید به شکل زیر تغییر یابد:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/>
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
<section name="errorTweet" requirePermission="false" type="Elmah.ErrorTweetSectionHandler, Elmah"/>
</sectionGroup>
</configSections>
<elmah>
<security allowRemoteAccess="1" />
<errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="cn1" />
</elmah>
<appSettings/>
<connectionStrings>
<add name="cn1" connectionString="data source=~/ErrorsLog/Errors.db" />
</connectionStrings>
<system.web>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
</httpModules>
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<compilation debug="true"/>
<authentication mode="Windows" />
</system.web>
</configuration>
سادهترین تنظیم این ماژول استفاده از حالت xml است که به ازای هر خطا یک فایل xml را تولید کرده و نیاز به اسمبلی دیگری بجز ماژول مربوطه نخواهد داشت.
تذکر:
از لحاظ امنیتی مثال فوق توصیه نمیشود زیرا allowRemoteAccess آن 1 است و قسمت authorization ذکر نشده است. این مثال فقط جهت راه اندازی و آزمایش اولیه ارائه گردیده است. (همچنین بهتر است این نام پیش فرض را به نامی دیگر مثلا myloggermdl.axd تغییر داده و در قسمت httpHandlers تنظیم نمائید. سپس این نام را به تگ location نیز اضافه کنید)
اکنون برای مشاهده خروجی این ماژول به انتهای آدرس سایت خود، elmah.axd را اضافه کرده و سپس enter کنید:
همانطور که در تصویر مشخص است، تمامی خطاهای لاگ شده گزارش داده شدهاند. همچنین دو نوع فید به همراه امکان دریافت خطاها به صورت CSV نیز موجود است. با کلیک بر روی لینک details ، صفحهی بسیار ارزندهای ارائه میشود که تقریبا نحوهی وقوع ماجرا را بازسازی میکند.
نکتهی مهمی که در صفحهی جزئیات ارائه میشود (علاوه بر stack trace و مشخصات کاربر)، مقادیر تمامی فیلدهای یک صفحه هنگام بروز خطا است (قسمت Raw/Source data in XML or in JSON در این صفحه) :
به این صورت دیگر نیازی نیست از کاربر بپرسید چه چیزی را وارد کرده بودید که خطا حاصل شد. دقیقا مقادیر فیلدهای همان صفحهی زمان بروز خطا نیز برای شما لاگ میگردد.
نکته:
ماژول SQLite ایی که به همراه مجموعه ELMAH ارائه میشود 32 بیتی کامپایل شده (64 بیتی آن نیز موجود است که باید از آن در صورت لزوم استفاده شود). بنابراین برای اینکه در یک سرور 64 بیتی به مشکل برنخورید و خطای BadImageFormat را دریافت نکنید نیاز است تا به این نکته دقت داشت.
برای مطالعه بیشتر:
Error Logging Modules And Handlers
Sending ELMAH Errors Via GMail
Exception-Driven Development
Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components
ASP.NET MVC #11
آیا منظور شما اینه که تاریخ شمسی رو بصورت string توی دیتابیس بریزیم ؟
>> PersianDate : VARCHAR
>> Date : DATE
بدین صورت جهت استخراج تاریخهای شمسی و زدن کوئری به یک عدد پروسیجر بزرگ نیاز خواهیم داشت (مثلا بر اساس "/" اسپلیت کنه و بعد هر بخش رو int کنه و ....)
آیا چاره دیگری نداریم ؟ :(
NuGet 2.0 منتشر شد
نسخه جدید برنامه مدیریت بستههای دات نت هم آماده شد. میتونین از اینجا دانلودش کنین. (2.5MB)
طبق آمار خود سایت نوگت تا حالا بیش از 14.6 میلیون بار بستههای اون توسط کاربران دانلود شدن و بیش از 7000 بسته متمایز در این گالری موجوده!
یکی از مشکلاتی که تو این نسخه رفع شده موردی بود که در ارتباطات کند اینترنت بوجود میومد (^). تو کنسول این افزونه پس از وارد کردن قسمتی از نام یک بسته با فشردن کلید TAB نام تمام بستههایی که اول اسمشون اون عبارت تایپ شده باشه، لیست میشه (Tab Completion).
این عملیات در نسخههای قبلی با استفاده از یک درخواست HTML به OData (^) انجام میشد که دادههایی بیش از حد نیاز رو برمیگردوند. اما تو این نسخه این عملیات با استفاده از یک درخواست سریع JSON انجام میشه. (^)
من خودم این ویژگی رو تست کردم و افزایش سرعتش قابل ملاحظه بود!
یکی دیگه بهبودهای حاصله در دریافت بستههای وابسته نسبت به نسخه دات نت فریمورک در پروژه هدف هستش. یعنی میشه تنظیماتی روی بستههای نوگت اعمال کرد تا به صورت هوشمندانه نسخه متناسب با دات نت فریمورک مورد استفاده رو دانلود و نصب کنه.
اگه به صفحه مربوط به مشکلات و درخواستهای کاربران برای این افزونه (^) مراجعه کنین میبینید این دو موردکه تو این نسخه برطرف شدن بیشترین تقاضا رو داشتن. مورد اول با توجه به سرعت پایین اینترنت برای خود من خیلی کاربردیه.
نکته: اگر از VS 2010 SP1 استفاده میکنین هنگام به روز رسانی نوگت با استفاده از Extension Manager خود VS ممکنه با خطا مواجه بشین. اصولا بهترین روش نصب نوگت ابتدا unistall کردن نسخه قدیمی این افزونه از طریق appwiz.cpl و سپس نصب نسخه جدید با اجرای فایل vsix. هست (در هر دو قسمت نیاز به دسترسی administrator دارین).
و در نهایت:
You can develop your own package and share it via the NuGet Gallery. (^)
ویرایش:
متاسفانه دیروز وقت نکردم نتایج آزمایش با Fiddler رو اینجا بزارم.
مورد اول (Tab Completion) رو با سه نسخه از نوگت (1.6 و 1.8 و 2.0) برای دو عبارت jque و signa تست کردم و نتایج بدست اومده به شرح زیره. در زیر url درخواست مربوطه به همراه حجم دیتای دریافتی آورده شده:
نوگت 1.6:
nuget ver 1.6 jque: GET https://nuget.org/api/v2/Packages()?$orderby=DownloadCount%20desc,Id&$filter=startswith(tolower(Id),'jque')%20and%20IsLatestVersion&$skip=0&$top=90 HTTP/1.1 53691 bytes signa: GET https://nuget.org/api/v2/Packages()?$orderby=DownloadCount%20desc,Id&$filter=startswith(tolower(Id),'signa')%20and%20IsLatestVersion&$skip=0&$top=90 HTTP/1.1 11536 bytes
نوگت 1.8:
nuget ver 1.8 jque: GET https://nuget.org/api/v2/Packages()?$orderby=DownloadCount%20desc,Id&$filter=startswith(tolower(Id),'jque')%20and%20IsLatestVersion&$skip=0&$top=90 HTTP/1.1 53694 bytes signa: GET https://nuget.org/api/v2/Packages()?$orderby=DownloadCount%20desc,Id&$filter=startswith(tolower(Id),'signa')%20and%20IsLatestVersion&$skip=0&$top=90 HTTP/1.1 11536 bytes
نوگت 2.0:
nuget ver 2.0 jque: GET https://nuget.org/api/v2/package-ids?partialId=jque HTTP/1.0 598 bytes signa: GET https://nuget.org/api/v2/package-ids?partialId=signa HTTP/1.0 457 bytes
پاسخ سرور به عبارت signa در نسخه 2.0:
HTTP/1.1 200 OK Cache-Control: private Content-Type: application/json; charset=utf-8 Server: Microsoft-IIS/7.0 X-AspNetMvc-Version: 3.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Thu, 28 Jun 2012 07:23:06 GMT Connection: close Content-Length: 457 ["SignalR","SignalR.Client","SignalR.Client.Silverlight","SignalR.Client.Silverlight5","SignalR.Client.WP7","SignalR.EventStream","SignalR.Hosting.AspNet","SignalR.Hosting.Common","SignalR.Hosting.Owin","SignalR.Hosting.Self","SignalR.Js","SignalR.MicroSliver","SignalR.Ninject","SignalR.RabbitMq","SignalR.Reactive","SignalR.Redis","SignalR.Sample","SignalR.Server","SignalR.StructureMap","SignalR.WebSockets","SignalR.WindowsAzureServiceBus","Signals.js"]
میبینید که غیرقابل مقایسه هستن! و همونوطور که آقای هنسلمن (^) در مورد نسخههای قدیمی گفتن: «دادههای بیش از حد نیاز رو برمیگردونن»
نسخههای قبل از 2.0 همگی از odata استفاده میکردن و دادههای برگشتی تماما encrypt شدهاند. اما در نسخه 2.0 دادههای برگشتی از نوع JSON هست (به Fiddler مراجعه کنین تا تفاوت واقعی رو ببینین. البته برای اینکه دادههای encrypt شده رو در fiddler ببینین باید طبق راهنمایی خودش از تنظیمات مربوط به decrypt ترافیک https استفاده کنین)
متدهای کمکی مفید در پروژه های asp.net mvc
در اینجا تبدیل تاریخ مدنظر را باید همان طرف کدهای کنترلر انجام داد. یا این طرف از توابع جاوا اسکریپتی تبدیل تاریخ میلادی به شمسی باید استفاده کرد. دو context مختلف را نمیشود در آن واحد با هم ترکیب کرد.
البته میشود داخل کدهای جاوا اسکریپتی یک View از کدهای مثلا Razor استفاده کرد اما این کدها در زمان اجرا به صورت جاوا اسکریپتی پردازش و رندر میشوند و نه به فرمت مثلا سی شارپ. برای نمونه میشود در یک View داخل کدهای JavaScript موجود از Url.Action استفاده کرد. این مورد در زمان اجرا فقط تبدیل به یک رشته JavaScript میشود. البته این نکته برای بکارگیری Html.FarsiDateAndTime نیز صدق میکند و فراخوانی آن باید داخل کدهای Ajax جاوا اسکریپتی یک View باشد (و نه خارج از آن چون context دیگر JavaScript نخواهد بود). همچنین باید درنظر داشت که Html.FarsiDateAndTime در زمان رندر شدن جاوا اسکریپت موجود در یک View، تبدیل به معادل رشتهای آن شده و جایگزین میشود. یعنی در قسمت نتیجه یک عملیات Ajax قابل استفاده نخواهد بود.
ASP.NET MVC #22
تهیه سایتهای چند زبانه و بومی سازی نمایش اطلاعات در ASP.NET MVC
زمانیکه دات نت فریم ورک نیاز به انجام اعمال حساس به مسایل بومی را داشته باشد، ابتدا به مقادیر تنظیم شده دو خاصیت زیر دقت میکند:
الف) System.Threading.Thread.CurrentThread.CurrentCulture
بر این اساس دات نت میتواند تشخیص دهد که برای مثال خروجی متد DateTime.Now.ToString در کانادا و آمریکا باید با هم تفاوت داشته باشند. مثلا در آمریکا ابتدا ماه، سپس روز و در آخر سال نمایش داده میشود و در کانادا ابتدا سال، بعد ماه و در آخر روز نمایش داده خواهد شد. یا نمونهی دیگری از این دست میتواند نحوه نمایش علامت واحد پولی کشورها باشد.
ب) System.Threading.Thread.CurrentThread.CurrentUICulture
مقدار CurrentUICulture بر روی بارگذاری فایلهای مخصوصی به نام Resource، تاثیر گذار است.
این خواص را یا به صورت دستی میتوان تنظیم کرد و یا ASP.NET، این اطلاعات را از هدر Accept-Language دریافتی از مرورگر کاربر به صورت خودکار مقدار دهی میکند. البته برای این منظور نیاز است یک سطر زیر را به فایل وب کانفیگ برنامه اضافه کرد:
<system.web>
<globalization culture="auto" uiCulture="auto" />
یا اگر نیاز باشد تا برنامه را ملزم به نمایش اطلاعات Resource مرتبط با فرهنگ بومی خاصی کرد نیز میتوان در همین قسمت مقادیر culture و uiCulture را دستی تنظیم نمود و یا اگر همانند برنامههایی که چند لینک را بالای صفحه نمایش میدهند که برای مثال به نگارشهای فارسی/عربی/انگلیسی اشاره میکند، اینکار را با کد نویسی نیز میتوان انجام داد:
System.Threading.Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.CreateSpecificCulture("fa");
جهت آزمایش این مطلب، ابتدا تنظیم globalization فوق را به فایل وب کانفیگ برنامه اضافه کنید. سپس به مسیر زیر در IE مراجعه کنید:
IE -> Tools -> Intenet options -> Genarl tab -> Languages
در اینجا میتوان هدر Accept-Language را مقدار دهی کرد. برای نمونه اگر مقدار زبان پیش فرض را به فرانسه تنظیم کنیم (به عنوان اولین زبان تعریف شده در لیست) و سپس سعی در نمایش مقدار decimal زیر را داشته باشیم:
string.Format("{0:C}", 10.5M)
اگر زبان پیش فرض، انگلیسی آمریکایی باشد، $ نمایش داده خواهد شد و اگر زبان به فرانسه تنظیم شود، یورو در کنار عدد مبلغ نمایش داده میشود.
تا اینجا تنها با تنظیم culture=auto به این نتیجه رسیدهایم. اما سایر قسمتهای صفحه چطور؟ برای مثال برچسبهای نمایش داده شده را چگونه میتوان به صورت خودکار بر اساس Accept-Language مرجح کاربر تنظیم کرد؟ خوشبختانه در دات نت، زیر ساخت مدیریت برنامههای چند زبانه به صورت توکار وجود دارد که در ادامه به بررسی آن خواهیم پرداخت.
آشنایی با ساختار فایلهای Resource
فایلهای Resource یا منبع، در حقیقت فایلهایی هستند مبتنی بر XML با پسوند resx و هدف آنها ذخیره سازی رشتههای متناظر با فرهنگهای مختلف میباشد و برای استفاده از آنها حداقل یک فایل منبع پیش فرض باید تعریف شود. برای نمونه فایل mydata.resx را در نظر بگیرید. برای ایجاد فایل منبع اسپانیایی متناظر، باید فایلی را به نام mydata.es.resx تولید کرد. البته نوع فرهنگ مورد استفاده را کاملتر نیز میتوان ذکر کرد برای مثال mydata.es-mex.resx جهت فرهنگ اسپانیایی مکزیکی بکارگرفته خواهد شد، یا mydata.fr-ca.resx به فرانسوی کانادایی اشاره میکند. سپس مدیریت منابع دات نت فریم ورک بر اساس مقدار CurrentUICulture جاری، اطلاعات فایل متناظری را بارگذاری خواهد کرد. اگر فایل متناظری وجود نداشت، از اطلاعات همان فایل پیش فرض استفاده میگردد.
حین تهیه برنامهها نیازی نیست تا مستقیما با فایلهای XML منابع کار کرد. زمانیکه اولین فایل منبع تولید میشود، به همراه آن یک فایل cs یا vb نیز ایجاد خواهد شد که امکان دسترسی به کلیدهای تعریف شده در فایلهای XML را به صورت strongly typed میسر میکند. این فایلهای خودکار، تنها برای فایل پیش فرض mydata.resx تولید میشوند،از این جهت که تعاریف اطلاعات سایر فرهنگهای متناظر نیز باید با همان کلیدهای فایل پیش فرض آغاز شوند. تنها «مقادیر» کلیدهای تعریف شده در کلاسهای منبع متفاوت هستند.
اگر به خواص فایلهای resx در VS.NET دقت کنیم، نوع Build action آنها به embedded resource تنظیم شده است.
مثالی جهت بررسی استفاده از فایلهای Resource
یک پروژه جدید خالی ASP.NET MVC را آغاز کنید. فایل وب کانفیگ آنرا ویرایش کرده و تنظیمات globalization ابتدای بحث را به آن اضافه کنید. سپس مدل، کنترلر و View متناظر با متد Index آنرا با محتوای زیر به پروژه اضافه نمائید:
namespace MvcApplication19.Models
{
public class Employee
{
public int Id { set; get; }
public string Name { set; get; }
}
}
using System.Web.Mvc;
using MvcApplication19.Models;
namespace MvcApplication19.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var employee = new Employee { Name = "Name 1" };
return View(employee);
}
}
}
@model MvcApplication19.Models.Employee
@{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<fieldset>
<legend>Employee</legend>
<div class="display-label">
Name
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>
</fieldset>
<fieldset>
<legend>Employee Info</legend>
@Html.DisplayForModel()
</fieldset>
قصد داریم در View فوق بر اساس uiCulture کاربر مراجعه کننده به سایت، برچسب Name را مقدار دهی کنیم. اگر کاربری از ایران مراجعه کند، «نام کارمند» نمایش داده شود و سایر کاربران، «Employee Name» را مشاهده کنند. همچنین این تغییرات باید بر روی متد Html.DisplayForModel نیز تاثیرگذار باشد.
برای این منظور بر روی پوشه Views/Home که محل قرارگیری فایل Index.cshtml فوق است کلیک راست کرده و گزینه Add|New Item را انتخاب کنید. سپس در صفحه ظاهر شده، گزینه «Resources file» را انتخاب کرده و برای مثال نام Index_cshtml.resx را وارد کنید.
به این ترتیب اولین فایل منبع مرتبط با View جاری که فایل پیش فرض نیز میباشد ایجاد خواهد شد. این فایل، به همراه فایل Index_cshtml.Designer.cs تولید میشود. سپس همین مراحل را طی کنید، اما اینبار نام Index_cshtml.fa.resx را حین افزودن فایل منبع وارد نمائید که برای تعریف اطلاعات بومی ایران مورد استفاده قرار خواهد گرفت. فایل دومی که اضافه شده است، فاقد فایل cs همراه میباشد.
اکنون فایل Index_cshtml.resx را در VS.NET باز کنید. از بالای صفحه، به کمک گزینه Access modifier، سطح دسترسی متدهای فایل cs همراه آنرا به public تغییر دهید. پیش فرض آن internal است که برای کار ما مفید نیست. از این جهت که امکان دسترسی به متدهای استاتیک تعریف شده در فایل خودکار Index_cshtml.Designer.cs را در View های برنامه، نخواهیم داشت. سپس دو جفت «نام-مقدار» را در فایل resx وارد کنید. مثلا نام را Name و مقدار آنرا «Employee Name» و سپس نام دیگر را NameIsNotRight و مقدار آنرا «Name is required» وارد نمائید.
در ادامه فایل Index_cshtml.fa.resx را باز کنید. در اینجا نیز دو جفت «نام-مقدار» متناظر با فایل پیش فرض منبع را باید وارد کرد. کلیدها یا نامها یکی است اما قسمت مقدار اینبار باید فارسی وارد شود. مثلا نام را Name و مقدار آنرا «نام کارمند» وارد نمائید. سپس کلید یا نام NameIsNotRight و مقدار «لطفا نام را وارد نمائید» را تنظیم نمائید.
تا اینجا کار تهیه فایلهای منبع متناظر با View جاری به پایان میرسد.
در ادامه با کمک فایل Index_cshtml.Designer.cs که هربار پس از تغییر فایل resx متناظر آن به صورت خودکار توسط VS.NET تولید و به روز میشود، میتوان به کلیدها یا نامهایی که تعریف کردهایم، در قسمتهای مختلف برنامه دست یافت. برای نمونه تعریف کلید Name در این فایل به نحو زیر است:
namespace MvcApplication19.Views.Home {
public class Index_cshtml {
public static string Name {
get {
return ResourceManager.GetString("Name", resourceCulture);
}
}
}
}
بنابراین برای استفاده از آن در هر View ایی تنها کافی است بنویسیم:
@MvcApplication19.Views.Home.Index_cshtml.Name
به این ترتیب بر اساس تنظیمات محلی کاربر، اطلاعات به صورت خودکار از فایلهای Index_cshtml.fa.resx فارسی یا فایل پیش فرض Index_cshtml.resx، دریافت میگردد.
علاوه بر امکان دسترسی مستقیم به کلیدهای تعریف شده در فایلهای منبع، امکان استفاده از آنها توسط data annotations نیز میسر است. در این حالت میتوان مثلا پیغامهای اعتبار سنجی را بومی کرد یا حین استفاده از متد Html.DisplayForModel، بر روی برچسب نمایش داده شده خودکار، تاثیر گذار بود. برای اینکار باید اندکی مدل برنامه را ویرایش کرد:
using System.ComponentModel.DataAnnotations;
namespace MvcApplication19.Models
{
public class Employee
{
[ScaffoldColumn(false)]
public int Id { set; get; }
[Display(ResourceType = typeof(MvcApplication19.Views.Home.Index_cshtml),
Name = "Name")]
[Required(ErrorMessageResourceType = typeof(MvcApplication19.Views.Home.Index_cshtml),
ErrorMessageResourceName = "NameIsNotRight")]
public string Name { set; get; }
}
}
همانطور که ملاحظه میکنید، حین تعریف ویژگیهای Display یا Required، امکان تعریف نام کلاس متناظر با فایل resx خاصی وجود دارد. به علاوه ErrorMessageResourceName به نام یک کلید در این فایل و یا پارامتر Name ویژگی Display نیز به نام کلیدی در فایل منبع مشخص شده، اشاره میکنند. این اطلاعات توسط متدهای Html.DisplayForModel، Html.ValidationMessageFor، Html.LabelFor و امثال آن به صورت خودکار مورد استفاده قرار خواهند گرفت.
نکتهای در مورد کش کردن اطلاعات
در این مثال اگر فیلتر OutputCache را بر روی متد Index تعریف کنیم، حتما نیاز است به هدر Accept-Language نیز دقت داشت. در غیراینصورت تمام کاربران، صرفنظر از تنظیمات بومی آنها، یک صفحه را مشاهده خواهند کرد:
[OutputCache(Duration = 60, VaryByHeader = "Accept-Language")]
public ActionResult Index()
معرفی Bit Platform
وب اسمبلی چیست؟
<BlazorMode> ... </BlazorMode> <WebAppDeploymentType> ... </WebAppDeploymentType>
- وجود سیستم Exception handling در سرور و کلاینت (این موضوع به گونه ای بر اساس Best Practiceها پیاده سازی شده که اپلیکیشن را از بروز هر خطایی که بخواهد موجب Crash کردن برنامه شود ایزوله کرده)
- وجود سیستم User Authentication بر اساس JWT که شما در همان ابتدا که از این تمپلیت پروژه جدیدی میسازید صفحات SignIn ، SignUp را خواهید داشت.
- پکیج Bit Blazor UI که بالاتر درمورد آن صحبت کرده ایم از همان ابتدا در TodoTemplate نصب و تنظیم شده تا بتوانید به راحتی صفحات جدید با استفاده از آن بسازید.
- کانفیگ استاندارد Swagger در سمت سرور.
- ارسال ایمیل در روند SignUp.
- وجود خاصیت AutoInject برای سادهسازی تزریق وابستگی ها.
- و بسیاری موراد دیگر که در داکیومنتهای پروژه میتوانید آنهارا ببینید.
- شما میتوانید این پروژه را در گیتهاب مشاهده کنید.
- برای اشکالات یا قابلیت هایی که میخواهید برطرف شود Issue ثبت کنید.
- پروژه را Fork کنید و Star دهید.
- ایشوهایی که وجود دارد را برطرف کنید و Pull Request ارسال کنید.
- برای در جریان بودن از روند توسعه در جلسات برنامه ریزی (Planning Meeting) و گزارشات هفتگی (Standup Meeting ) که همه اینها در Microsoft Teams برگزار میشود شرکت کنید.
دایرکتوریهای لینک در ایران
http://www.linkdoony.com/
http://www.iranget.com/