我正在尝试做一个简单的多语言网站。重写FindView以获取基于语言的文件很简单,我的问题出在路由部分。
我想做的是:(有一个网站有两种语言- pt-br和en-us,让缩写为onlu pt和en -默认为PT)
User types 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/时,将不会重定向到站点的根目录。
路由的另一个问题是,我不想让任何人输入控制器的名称,我只想要动作,我的网站只有一个主控制器,几乎没有动作。
另一个问题是我想要一个不同的动作名称,如英文的联系人和葡萄牙语的CONTATO,它们应该出现在地址栏上,如www.mysite.com/ CONTACT或www.mysite.com/en/Contact
Mu引擎我基于Guido Breitenhuber的这个解决方案http://www.counity.at/blog/2012/asp-net-mvc3-localization-using-culture-dependent-views/
这是一些调整过的代码(它还不能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;
        }
    }
}发布于 2012-11-28 20:55:32
好吧,经过一段时间尝试以最好的方式做,我发现了一个更容易和更快的解决方案。
我只是在global.asax中一个接一个地绘制了我想要的路由。如果你只有很少的页面和语言,这是可行的,而且实现起来也很快。
    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" });https://stackoverflow.com/questions/13587491
复制相似问题