چند زبانه کردن مسیریابی در ASP.NET 5 و MVC 6

یکشنبه 6 دی 1394

در این مقاله نحوه دو زبانه کردن محتوای صفحات سایت و همچنین بومی سازی مسیرها یا همان Route را آموزش خواهیم داد. این کار را در یک پروژه mvc انجام خواهیم داد

چند زبانه کردن مسیریابی در ASP.NET 5 و MVC 6

برای این کار ابتدا یک پروژه MVC ایجاد کنید .در این جا نوع پروژه را Empty در نظر نگرفته ایم ولی فرقی هم در نتیجه مورد نظر نخواهد داشت .

بعد از ایجاد پروژه برای اینکه به MVC امکان استفاده از زبان مورد نظر خود را بدهیم لازم است تا منبعی که باید داده های خود را از آن بخواند در اختیارش قرار دهیم .برای این کار طبق شکل زیر یک Resource برای پروژه خود ایجاد می کنیم . یک application folder جدید به نام “App_GlobalResources” ایجاد می کنیم .در این فایل طبق مقادیر Key و Value مقادیر مورد نظر از زبان دلخواه را وارد می کنیم .

بعد از این کار دو فایل جداگانه Resource برای زبان انگلیسی و فارسی ایجاد می کنیم. بر روی فولدر “App_GlobalResources” راست کلیک کرده، "Add" را انتخاب و روی “Resource file” کلیک می کنیم و نام آن را به "Notifications" تغییر داده و OK می کنیم.

بعد از افزودن دو فایل Resource شکل solution Explorer مانند زیر است .

حال به ویرایش فایل منبع فارسی و انگلیسی که اضافه کرده ایم می کنیم .مانند شکل زیر معادل فارسی کلید های را وارد می کنیم .

یک کنترلر Empty به نام Demo ایجاد می کنیم . در داخل این کنترلر یک Action به نام Index ایجاد می کنیم .برای این Action یک View از نوع Empty ایجاد می کنیم . ساختار View به شکل زیر خواهد بود

اگر برنامه را اجرا کنید شکل زیر را خواهید دید

بعد از این کار نوبت به Action بازگشتی این فرم است .یعنی پس از اینکه کاربر بر روی دکمه Submit  کلیک کرد به کجا برود و چه عملیاتی انجام شود . برای این کار یک Action همنام Index ایجاد می کنیم .برای این Action یک صفت [httppost] در نظر می گیریم .کدهای مربوط به این Action به صورت زیر است

 public ActionResult Index(FormCollection collection)
        {
            TempData.Add("LoggedInUser", collection["txtName"]);
            string language = collection["ddlLanguage"];
            SetCulture(language);

            return RedirectToAction("Home");
        }

همانطور که می بینید در این کد از یک TempData استفاده شده است . TempData یک دیکشنری برای ذخیره اطلاعات است . TempData در پشت صحنه برای ذخیره اطلاعات از Session استفاده می کند.ولی با آن متفاوت است .بعد از خوانده شدن TempData بلافاصله پاک می شود. در ورودی Action هر چیزی که از سمت فرم به ما ارسال شده است را در داخل پارامتر از نوع FormCollection از فرم دریافت می کنیم .سپس از این کالکشن اطلاعات مربوط به txtName و همچنین انتخابی که کاربر در DropdownList انجام داده است را دریافت کرده و در داخل یک TempData ذخیره می کنیم . در داخل این Action متد SetCulture را نیز صدا کرده ایم .

کد مربوط به این متد در زیر آورده شده است .

 private void SetCulture(string cultureCode)
        {

            var cookieCultureLanguage = new HttpCookie("UserLanguage")
            {
                Value = cultureCode
            };

            Response.Cookies.Set(cookieCultureLanguage);

            //Sets  Culture for Current thread
            Thread.CurrentThread.CurrentCulture =
            System.Globalization.CultureInfo.CreateSpecificCulture("en");

            //Ui Culture for Localized text in the UI
            Thread.CurrentThread.CurrentUICulture =
            new System.Globalization.CultureInfo(cultureCode);

        }

در داخل این متد زبانی که کاربر در داخل dropdownlist انتخاب کرده است به عنوان پارامتر دریافت می شود .سپس از انجایی که توسط TempData اطلاعات مربوط به انتخاب زبان کاربر را ذخیره کرده بودیم ، می توانیم Value مربوط به هر انتخاب را هم داشته باشیم .با این اطلاعات و با زبانی که کاربر انتخاب کرده است برای او یک Cookie ست می شود.و بعد از آن توسط دستور

Thread.CurrentThread.CurrentUICulture =new system.Globalization.CultureInfo(cultureCode);

 به تغییر زبان جاری  می پردازیم .

بعد از این کار به View مربوطه هدایت خواهیم شد . بعد از این در هر جای برنامه اطلاعات مربوط به زبان از Resource مرتبط با آن خوانده خواهد شد.

در قسمت BundelConfig.cs هم کدهای زیر را نوشته ایم


            var lstLangCultures = new List<string>() { "en", "fa" };

            //Loops through available languages to add language specific

            //JavaScript minified bundles

            foreach (var cultureName in lstLangCultures)

            {

                var extJsNotifications = new Bundle(string.Format("~/Scripts/Notifications-{0}",

                                        cultureName))

                   .Include("~/Scripts/UserNotifications.js")

                   .Include("~/Scripts/UserOperations.js");

                extJsNotifications.Transforms.Clear();

                extJsNotifications.Transforms.Add(new JSTranslator());

                extJsNotifications.Transforms.Add(new JsMinify());

                bundles.Add(extJsNotifications);

            }

 

همچنین برای اینکه Bundel که ایجاد کرده ایم هم بتواند با resource های ما کار کند به کد زیر احتیاج داریم

 


namespace Localized

{

    public class HtmlHelpers

    {

        /// <summary>

        /// Localized JavaScript bundle

        /// </summary>

        /// <param name="fileName"></param>

        /// <returns></returns>

        public static HtmlString LocalizedJsBundle(string fileName)

        {

            string culture;

            var cookie = HttpContext.Current.Request.Cookies["UserLanguage"];

            if (cookie != null && cookie.Value != null

                && cookie.Value.Trim() != string.Empty)

                culture = cookie.Value;

            else

                culture = "en";

            fileName = string.Concat(fileName, "-", culture);

            var output = (HtmlString)System.Web.Optimization.Scripts

                .Render(fileName);

            return output;

        }


در ادامه به توضیح نحوه چند زبانه کردن مسیریابی در mvc می پردازیم .مراحل این کار هم تقریبا مانند قبل است .برای این کار ابتدا در داخل یک کنترلر Action هایی به صورت زیر تعریف می کنیم

[LocalizedRoute("order", Name = "order")]

   public Order GetAll()

   {

      //omitted for brevity

   }


   [LocalizedRoute("order/{id:int}", Name = "orderById")]

   public Order GetById(int id)

   {

      //omitted for brevity

   }

 سپس در داخل یک کلاس که از RouteAttribute ارث بری می کند کدهای زیر را می نویسی

public class LocalizedRouteAttribute : RouteAttribute

{

    public LocalizedRouteAttribute(string template) : base(template)

    {

        Culture = "en-Ca";

    }


    public string Culture { get; set; }

}

در داخل کلاس StartUp پروژه کدهای زیر را می نویسیم

public class Startup

{

    public void ConfigureServices(IServiceCollection services)

    {

        var localizedRoutes = new Dictionary<string, LocalizedRouteInformation[]>

        {

            {

                "order", new[]

                {

                    new LocalizedRouteInformation("de-CH", "auftrag"),

                    new LocalizedRouteInformation("pl-PL", "zamowienie"),

                }

            },

            {

                "orderById", new[]

                {

                    new LocalizedRouteInformation("de-CH", "auftrag/{id:int}"),

                    new LocalizedRouteInformation("pl-PL", "zamowienie/{id:int"),

                }

            }

        };


        services.AddMvc(o => o.AddLocalizedRoutes(localizedRoutes));

    }


    public void Configure(IApplicationBuilder app, IHostingEnvironment env)

    {

        app.UseMvc();

    }

}

به همین منوال می توانید مسیرهای خود را هم به زبان دلخواه costomize کنید.

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید