استخدام Globalization and Localization مع ملفات Resource

-

في هذا الدرس بنتلعم كيف بنستخدم ملفات resource file (.resx) الخاصة ب بـ ASP.NET Core ،هذه الملفات مهمه ومفيده عند التعامل مع culture في المواقع والتطبيقات.تستخدم هذه الملفات عند تطبيق اكثر من لغة في التطبيق او الموقع بحيث يتم اضافة النصوص المطلوبة لكل لغة. وبعدها بتم تطبيق الملف resource file (.resx) حسب اللغة المختاره

بنطبق في هذا المثال اللغة الانجليزية والعربية. وبنتعلم مجموعة من الاشياء وهي :


بنحتاج قبل البدء الى تعريف class باسم LocalizationService في مجلد Resources اضف هذا class بعد اضافة مجلد باسم Resources وبعدها ضيف الكود التالي: 

 public class LocalizationService
    {
        private readonly IStringLocalizer _localizer;
        public LocalizationService(IStringLocalizerFactory factory)
        {
            var type = typeof(Resource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName!);
            _localizer = factory.Create("Resource", assemblyName.Name);
        }
        public LocalizedString GetLocalizedHtmlString(string key)
        {
            return _localizer[key];
        }
    }
في هذا class عرفنا LocalizationService الي بتقرأ البيانات من ملفات Resource وبالاخير رجعنا هذه القيم على شكل String باستخدام LocalizedString 
تمام واكيد حتي نقدر نستخدم هذه الخدمات اكيد بنحتاج الى تعريفها في  ConfigureServices() method لذا قم باضافة الكود التالي داخل ConfigureServices() method في ملف Startup:
 services.AddLocalization(options => options.ResourcesPath = "Resources");
 services.AddSingleton<LocalizationService>();
وما تنسي تضيف Namespace الخاص بهذا الكود وهو : 
using Globalization.Resources;
نكمل العمل على الاعدادات في ملف Startup class ونضيف الكود التالي الى ()ConfigureServices.
 public void ConfigureServices(IServiceCollection services) { //localization & globalization  services.AddMvc().AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix); services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[]{new CultureInfo("en-US"),new CultureInfo("ar-jo")}; options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");options.SupportedCultures = supportedCultures;options.SupportedUICultures = supportedCultures;});}
واكيد هذا الكود محتاج اضافة مجموعة من namespaces لذا اضف ايضا في اول الملف :

using System.Globalization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
توضيح الكود السابق: 
الكود يعمل على تعريف شيئين:
  • أن تكون ميزة Localization جاهزة ل Data Annotations and Views.
  • تحديد اللغات التي بدعهما الموقع وهي هنا : اللغة الإنجلزية en-US ، العربية ar-jo
وحددنا بعدها اللغة الافتراضية في التطبيق وهي "en-US".
تمام واكيد حتي نقدر نستخدم هذه الخدمات اكيد بنحتاج الى تعريفها في  Configure() method لذا قم باضافة الكود التالي داخل Configure() method في ملف Startup:

 //localization & globalization
 var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
 app.UseRequestLocalization(locOptions.Value);
وبهيك بنكون خلصنا الاعدادت لتفعيل اللغات في التطبيق.

بنكمل شغل على مشروعنا السابق Globalization وبنطبق تغيير اللغة .
الان بنروح على ملف ViewImports.cshtml_ ونضيف الكود التالي: 
@using Globalization
@using Globalization.Models
@using Globalization.Resources
@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Localization
@using Microsoft.Extensions.Options
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions
@inject LocalizationService LocalizationService
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
مثل ما تعلمنا سابق الهدف من هذا الكود هو استخدام هذه Namespace دون الحاجه الى تكرارها في جميع Views. لاحظ ان عملنا inject@ لمجموعه من الاشياء منها LocalizationService وهذا هو المسؤول على ارجاع القيم من ملفات Resources.

تمام الان دور نعمل انشاء لملفات resource files داخل مجلد Resources في المشروع. اول خطوة ضيف class باسم Resource داخل هذا المجلد، تمام الان نضيف ملف من نوع Resource انقر يمين فوق مجلد Resources واختر Add New Item شوف الصورة :



اختر الاسم Resource.ar.resx بهدف اضافة القيم باللغة العربية،وكمان بنضيف ملف ثاني باسم Resource.en.resx بهدف اضافة القيم باللغة الإنجليزية وبكون شكل المشروع : 



تمام خلونا نضيف بعض القيم داخل هذه الملفات (شوف الصور في الاسفل)





تمام الان احنا جاهزين والتطبيق جاهز. طيب نطبق هذا الكلام في صفحة View ونشوف كيف القيم بتتغير حسب اللغة.
ننتقل الى Index View الخاصة Globalization ونعمل تعديل بسيط وهو : بدل كتابة الاسماء بشكل ثابت نغيرها الى الكود :
@LocalizationService.GetLocalizedHtmlString("ValueFromResourceFile") 
الكود السابق يقرا القيمة ValueFromResourceFile من ملفات Resource حسب اللغة المختارة. بناء عليه لازم نغير الاكود الى(شوف الاكواد باللون الاصفر هي التغيير الي حصل على View) :

@{
    ViewData["Title"] = "Home Page";
}
<div class="text-center">
    <h1 class="display-4">Welcome</h1>
</div>
@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Localization
@using Microsoft.Extensions.Options
@inject IOptions<RequestLocalizationOptions> LocOptions
@{
    var requestCulture = Context.Features.Get<IRequestCultureFeature>();
    var cultureItems = LocOptions.Value.SupportedUICultures
        .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
        .ToList();
}
<form id="cultureForm" asp-action="Index">
    <label>Language:</label>
    <select onchange="SetCulture(this.value)" asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
    </select>
</form>
<table class="table culture-table">
    <tr>
        <td>@LocalizationService.GetLocalizedHtmlString("Culture") </td>
        <td>
            @requestCulture.RequestCulture.Culture.Name
        </td>
    </tr>
    <tr>
        <td>@LocalizationService.GetLocalizedHtmlString("UICulture")</td>
        <td>
            @requestCulture.RequestCulture.UICulture.Name
        </td>
    </tr>
    <tr>
        <td>@LocalizationService.GetLocalizedHtmlString("Date")</td>
        <td>
            @DateTime.Now.ToLongDateString()
        </td>
    </tr>
    <tr>
        <td>@LocalizationService.GetLocalizedHtmlString("Currency")</td>
        <td>
            @(10000.00.ToString("c"))
        </td>
    </tr>
    <tr>
        <td>@LocalizationService.GetLocalizedHtmlString("Number")</td>
        <td>
            @(188.45m.ToString("F2"))
        </td>
    </tr>
</table>
<script>
    function SetCulture(selectedValue) {
        var culture = "/?culture=" + selectedValue + "&ui-culture=" + selectedValue;
        document.getElementById("cultureForm").action = culture;
        document.getElementById("cultureForm").submit();
    }
</script>
الان دور نشغل الصفحة ونشوف النتيجة:
شغل الصفحة وحاول تغيير اللغة وشوف النتيجة : 


وبعد تغيير اللغة بتكون النتيجة :