Razor 使用多个管线的本地化视图引擎

Razor 使用多个管线的本地化视图引擎,razor,localization,asp.net-mvc-4,locale,viewengine,Razor,Localization,Asp.net Mvc 4,Locale,Viewengine,我正在尝试制作一个简单的多语言网站。重写FindView以获取基于该语言的文件很容易,我的问题出现在路由部分 我想做的是:(有一个网站有两种语言-pt br和en us,让缩写为onlu pt和en-默认为pt) 用户类型www.mysite.com->将在用户头请求中找到语言,如果用户没有任何语言,他将被重定向到默认PT,因此最终结果将是葡萄牙语的www.mysite.com。如果他有en,他将被重定向到www.mysite.com/en/,结果将是英文视图 如果用户键入www.mysite.

我正在尝试制作一个简单的多语言网站。重写FindView以获取基于该语言的文件很容易,我的问题出现在路由部分

我想做的是:(有一个网站有两种语言-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/时,将不会重定向到站点的根目录

路由的另一个问题是,我不想让任何人键入控制器名称,我只想要操作,我的网站只有一个主控制器,几乎没有操作

另一个问题是,我想要一个不同的动作名称,比如英语的CONTACT和葡萄牙语的CONTATO,它们应该出现在地址栏上,比如www.mysite.com/CONTATO或www.mysite.com/en/CONTACT

Mu引擎我是根据这个解决方案

下面是一些调整的代码(它还没有100%工作)

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Web.Mvc;
利用制度全球化;
名称空间Ala.multi语言
{
公共类LocalizedViewLocation:RazorViewEngine
{
私有静态只读字符串[]_emptyLocations=新字符串[0];
公共字符串[]LocalizedViewLocationFormats{get;set;}
公共字符串[]LocalizedMasterLocationFormats{get;set;}
受保护字符串[]LocalizedPartialViewLocationFormats{get;set;}
公共本地化视图位置()
{
//定义本地化视图位置
//0:语言
//1:视图名称
//2:控制器名称
LocalizedViewLocationFormats=new[]{
“~/Views/{0}/{2}/{1}.cshtml”,
“~/Views/Shared/{0}/{1}.cshtml”};
MasterLocationFormats=新[]{
“~/Views/{0}/{2}/{1}.cshtml”,
“~/Views/Shared/{0}/{1}.cshtml”};
LocalizedPartialViewLocationFormats=new[]{
“~/Views/{0}/{2}/{1}.cshtml”,
“~/Views/Shared/{0}/{1}.cshtml”};
}
公共覆盖视图引擎结果FindPartialView(ControllerContext ControllerContext、字符串partialViewName、布尔useCache)
{
如果(controllerContext==null)
抛出新ArgumentNullException(“controllerContext”);
if(String.IsNullOrEmpty(partialViewName))
抛出新ArgumentException(“参数partialViewName为null或空。”,“partialViewName”);
搜索字符串[];
var controllerName=controllerContext.RouteData.GetRequiredString(“控制器”);
var partialPath=GetPath(controllerContext、LocalizedPartialViewLocationFormats、partialViewName、controllerName、out-searched);
if(String.IsNullOrEmpty(partialPath))
{
var baseRes=base.FindPartialView(controllerContext、partialViewName、useCache);
if(baseRes.View!=null)
返回基线;
返回新的ViewEngineResult(searched.Union(baseRes.SearchedLocations));
}
返回新的ViewEngineResult(CreatePartialView(controllerContext,partialPath),this);
}
public override ViewEngineResult FindView(ControllerContext ControllerContext、string viewName、string masterName、bool useCache)
{
如果(controllerContext==null)
抛出新ArgumentNullException(“controllerContext”);
if(String.IsNullOrEmpty(viewName))
抛出新ArgumentException(“参数viewName为null或空。”,“viewName”);
字符串[]viewLocationsSearched;
字符串[]主位置搜索;
var controllerName=controllerContext.RouteData.GetRequiredString(“控制器”);
var viewPath=GetPath(controllerContext、LocalizedViewLocationFormats、viewName、controllerName、OutViewLocationsSearched);
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)
返回基线;
返回新的ViewEngineResult(viewLocationsSearched.Union(masterLocationsSearched.Union)(baseRes.SearchedLocations));
}
返回新的ViewEngineResult(CreateView(controllerContext、viewPath、masterPath),此选项为;
}
私有字符串GetPath(ControllerContext ControllerContext,字符串[]位置,字符串名称,字符串controllerName,输出字符串[]搜索位置)
{
搜索位置=_清空位置;
if(String.IsNullOrEmpty(name))
返回字符串。空;
if(IsSpecificPath(名称))
返回字符串。空;
返回GetPathFromGeneralName(controllerContext、locations、name、controllerName、ref searchedLocations);
}
私有静态bool IsSpecificPath(字符串名称)
{
char c=名称[0];
返回(c='~'| c=='/');
}
私有字符串GetPa
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;
        }
    }
}
    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" });