0

シンプルな多言語ウェブサイトを作ろうとしています。言語に基づいてファイルを取得するために FindView をオーバーライドするのは簡単です。私の問題はルーティング部分にあります。

私がやりたいことは次のとおりです:(2つの言語のWebサイトを持っています-pt-brとen-us、省略してonlu ptとen-デフォルトはPTになります)

ユーザー タイプ www.mysite.com -> ユーザー ヘッダー リクエストで言語を検索し、ユーザーがそれらのいずれも持っていない場合、デフォルトの PT にリダイレクトされるため、最終結果は www.mysite.com になります。ポルトガル語で。彼が en を持っている場合、彼は www.mysite.com/en/ にリダイレクトされ、結果は英語で表示されます。

ユーザーが www.mysite.com/pt/ と入力した場合 -> 彼がデフォルトを望んでいることを確認し、ポルトガル語で www.mysite.com にリダイレクトします。

言語に基づいて正しいビューを取得するために、カスタム エンジンを作成しました。しかし、ルーティングの問題のため、100% は機能していません。

私の場合、ルーティングしようとしています

routes.MapRoute(
                "Localization", // Route name
                "{lang}/{controller}/{action}", // URL with parameters
                new { lang = "pt", controller = "Home", action = "Index" } //defaults
);

しかし、これにより、誰かが /pt/ と入力しても、サイトのルートにリダイレクトされません。

ルートに関するもう 1 つの問題は、コントローラー名を入力したくないということです。アクションが必要なだけです。私の Web サイトには、アクションがほとんどない Home コントローラーが 1 つしかありません。

もう 1 つの問題は、英語の CONTACT とポルトガル語の CONTATO のように、別のアクション名が必要なことです。それらは www.mysite.com/Contato または www.mysite.com/en/Contact のようにアドレス バーに表示されるはずです。

Mu Engine このソリューションに基づいて作成しましたhttp://www.counity.at/blog/2012/asp-net-mvc3-localization-using-culture-dependent-views/ by Guido Breitenhuber

これは、いくつかの調整を加えたコードです (まだ 100% は機能していません)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Globalization;

namespace Ala.MultiLanguage
{
    public class LocalizedViewLocation : RazorViewEngine
    {
        private static readonly string[] _emptyLocations = new string[0];

        public string[] LocalizedViewLocationFormats { get; set; }

        public string[] LocalizedMasterLocationFormats { get; set; }

        protected string[] LocalizedPartialViewLocationFormats { get; set; }

        public LocalizedViewLocation()
        {
            // Define the localized view locations
            //  0: Language
            //  1: View name
            //  2: Controller name

            LocalizedViewLocationFormats = new[] {
            "~/Views/{0}/{2}/{1}.cshtml",
            "~/Views/Shared/{0}/{1}.cshtml"};

            MasterLocationFormats = new[] {
            "~/Views/{0}/{2}/{1}.cshtml",
            "~/Views/Shared/{0}/{1}.cshtml"};

            LocalizedPartialViewLocationFormats = new[] {
            "~/Views/{0}/{2}/{1}.cshtml",
            "~/Views/Shared/{0}/{1}.cshtml"};
        }


        public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            if (controllerContext == null)
                throw new ArgumentNullException("controllerContext");

            if (String.IsNullOrEmpty(partialViewName))
                throw new ArgumentException("Parameter partialViewName is null or empty.", "partialViewName");

            string[] searched;

            var controllerName = controllerContext.RouteData.GetRequiredString("controller");

            var partialPath = GetPath(controllerContext, LocalizedPartialViewLocationFormats, partialViewName, controllerName, out searched);


            if (String.IsNullOrEmpty(partialPath))
            {
                var baseRes = base.FindPartialView(controllerContext, partialViewName, useCache);

                if (baseRes.View != null)
                    return baseRes;

                return new ViewEngineResult(searched.Union(baseRes.SearchedLocations));
            }

            return new ViewEngineResult(CreatePartialView(controllerContext, partialPath), this);
        }

        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            if (controllerContext == null)
                throw new ArgumentNullException("controllerContext");

            if (String.IsNullOrEmpty(viewName))
                throw new ArgumentException("Parameter viewName is null or empty.", "viewName");

            string[] viewLocationsSearched;

            string[] masterLocationsSearched;

            var controllerName = controllerContext.RouteData.GetRequiredString("controller");

            var viewPath = GetPath(controllerContext, LocalizedViewLocationFormats, viewName, controllerName, out viewLocationsSearched);

            var masterPath = GetPath(controllerContext, LocalizedMasterLocationFormats, masterName, controllerName, out masterLocationsSearched);


            if (String.IsNullOrEmpty(viewPath) || (String.IsNullOrEmpty(masterPath) && !String.IsNullOrEmpty(masterName)))
            {
                var baseRes = base.FindView(controllerContext, viewName, masterName, useCache);

                if (baseRes.View != null)
                    return baseRes;

                return new ViewEngineResult(viewLocationsSearched.Union(masterLocationsSearched).Union(baseRes.SearchedLocations));
            }

            return new ViewEngineResult(CreateView(controllerContext, viewPath, masterPath), this);
        }


        private string GetPath(ControllerContext controllerContext, string[] locations, string name, string controllerName, out string[] searchedLocations)
        {
            searchedLocations = _emptyLocations;

            if (String.IsNullOrEmpty(name))
                return String.Empty;

            if (IsSpecificPath(name))
                return String.Empty;

            return GetPathFromGeneralName(controllerContext, locations, name, controllerName, ref searchedLocations);
        }


        private static bool IsSpecificPath(string name)
        {
            char c = name[0];
            return (c == '~' || c == '/');
        }

        private string GetPathFromGeneralName(ControllerContext controllerContext, string[] locations, string name, string controllerName, ref string[] searchedLocations)
        {
            var result = String.Empty;

            searchedLocations = new string[locations.Length];

            for (int i = 0; i < locations.Length; i++)
            {
                var location = locations[i];

                var virtualPath = string.Format(CultureInfo.InvariantCulture, location, CultureInfo.CurrentUICulture.TwoLetterISOLanguageName, name, controllerName);

                if (FileExists(controllerContext, virtualPath))
                {
                    searchedLocations = _emptyLocations;

                    result = virtualPath;

                    break;
                }

                searchedLocations[i] = virtualPath;
            }

            return result;
        }
    }
}
4

1 に答える 1

0

さて、最善の方法で実行しようとしたいくつかのタイミングの後、私は1つのソリューションをはるかに簡単かつ迅速に実装できることを発見しました。

必要なルートをglobal.asaxに1つずつマップしました。これは機能し、ページと言語が少ない場合はすばやく実装できます。

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute("Default-BR", "", new { controller = "Home", action = "Index" });
    routes.MapRoute("Default-EN", "en", new { controller = "Home", action = "IndexEN" });

    routes.MapRoute("HotelBR", "Hotel", new { controller = "Home", action = "Index" });
    routes.MapRoute("HotelEN", "en/Hotel", new { controller = "Home", action = "IndexEN" });

    routes.MapRoute("Apartamento", "Apartamento", new { controller = "Home", action = "Apartamentos" });
    routes.MapRoute("Apartamentos", "Apartamentos", new { controller = "Home", action = "Apartamentos" });
    routes.MapRoute("Apartments", "en/Apartments", new { controller = "Home", action = "ApartamentosEN" });

    routes.MapRoute("Localizacao", "Localizacao", new { controller = "Home", action = "Localizacao" });
    routes.MapRoute("Location", "en/Location", new { controller = "Home", action = "LocalizacaoEN" });

    routes.MapRoute("Tarifa", "Tarifa", new { controller = "Home", action = "Tarifas" });
    routes.MapRoute("Tarifas", "Tarifas", new { controller = "Home", action = "Tarifas" });
    routes.MapRoute("Rates", "en/Rates", new { controller = "Home", action = "TarifasEN" });

    routes.MapRoute("Reserva", "Reserva", new { controller = "Home", action = "Reservas" });
    routes.MapRoute("Reservas", "Reservas", new { controller = "Home", action = "Reservas" });
    routes.MapRoute("Booking", "en/Booking", new { controller = "Home", action = "ReservasEN" });

    routes.MapRoute("Contato", "Contato", new { controller = "Home", action = "Contato" });
    routes.MapRoute("Contact", "en/Contact", new { controller = "Home", action = "ContatoEN" });
于 2012-11-28T12:55:31.793 に答える