加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 可以在ASP.NET MVC中本地化URL /路由吗?

发布时间:2020-12-15 22:48:39 所属栏目:asp.Net 来源:网络整理
导读:我正在与客户合作,希望我们的网络应用程序中的URL是法语.我是一名英语开发人员,我们也有英文客户.这是一个有趣的问题,但ASP.NET MVC框架不支持它. 这是场景.路线… 具体实施例 英文网址 www.stackoverflow.com/questions/ask 也会支持 法语URL www.stackover
我正在与客户合作,希望我们的网络应用程序中的URL是法语.我是一名英语开发人员,我们也有英文客户.这是一个有趣的问题,但ASP.NET MVC框架不支持它.

这是场景.路线…

具体实施例
英文网址
www.stackoverflow.com/questions/ask

也会支持

法语URL
www.stackoverflow.com/problème/poser

通用实例
英文网址
http://clientA.product.com/AreaNameEnglish/ControllerNameEnglish/ActionNameEnglish/params

也需要支持

法语URL
http://clientB.product.com/AreaNameFrench/ControllerNameFrench/ActionNameFrench/params

所以在MVC我的区域,控制器和操作都需要有英文和法文翻译.

显然,如果我要将所有我的控制器,视图和动作名称硬编码为法语,那么可维护性将是一个巨大的问题.有没有本地化浏览器中提供的路由,而不这样做?请记住,应用程序中有很多不同的路线.一对夫妇每个都有少数控制器,每个都有很多动作?

谢谢,
贾斯汀

编辑
感谢@womp这是迄今为止我已经提出的…尽管最后我采取了我发布的方式作为答案.

public class LocalizedControllerFactory : DefaultControllerFactory
{
    public override IController CreateController(RequestContext requestContext,string controllerName)
    {
        if (string.IsNullOrEmpty(controllerName))
            throw new ArgumentNullException("controllerName");

        if (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "fr")
        {
            controllerName = this.ReplaceControllerName(requestContext,controllerName);
            this.ReplaceActionName(requestContext);
            this.ReplaceAreaName(requestContext);
        }

        return base.CreateController(requestContext,controllerName);
    }

    private string ReplaceControllerName(RequestContext requestContext,string controllerName)
    {
        // would use the language above to pick the propery controllerMapper.  For now just have french
        Dictionary<string,string> controllerMapper = new Dictionary<string,string>()
        {
            {"frenchControllerA","englishControllerA"},{"frenchControllerB","englishControllerB"}
        };

        return this.ReplaceRouteValue(requestContext,"controller",controllerMapper);
    }

    private void ReplaceAreaName(RequestContext requestContext)
    {
        // would use the language above to pick the propery areaMapper.  For now just have french
        Dictionary<string,string> areaMapper = new Dictionary<string,string>()
        {
            {"frenchAreaX","englishAreaX"},{"frenchAreaY","englishAreaY"}
        };

        this.ReplaceRouteValue(requestContext,"area",areaMapper);
    }

    private void ReplaceActionName(RequestContext requestContext)
    {
        // would use the language above to pick the propery actionMapper.  For now just have french
        Dictionary<string,string> actionMapper = new Dictionary<string,string>()
        {
            {"frenchAction1","englishAction1"},{"frenchAction2","englishAction2"}
        };

        this.ReplaceRouteValue(requestContext,"action",actionMapper);
    }

    private string ReplaceRouteValue(RequestContext requestContext,string paramName,Dictionary<string,string> translationLookup)
    {
        if (requestContext.RouteData.Values[paramName] == null)
        {
            return null;
        }

        string srcRouteValue = requestContext.RouteData.Values[paramName] as string;
        if (srcRouteValue != null && translationLookup.ContainsKey(srcRouteValue))
        {
            requestContext.RouteData.Values[paramName] = translationLookup[srcRouteValue];
        }

        return requestContext.RouteData.Values[paramName] as string;
    }
}

一个体面的开始.如果我本地化在Url中的ControllerName和ActionName,它将会找到并呈现正确的View.但是我有以下问题.

区域名称不能翻译
本地化区域意味着Controller.View()方法无法查找视图.
尽管我已经在请求上下文中替换了区域名称,但是ViewEngineCollection.Find()方法似乎并没有被接受.我的Controller类中的“返回View()”的任何地方找不到其操作的默认视图.如果我没有本地化该区域,那么其他步骤就可以了.

RedirectToAction或Html.ActionLink
任何时候应用程序调用RedirectToAction,或者如果我使用Html.ActionLink帮助器或类似的Urls生成的东西是英文的.看起来我将不得不在多个地点添加逻辑,将英文网址转换为法语(或其他语言).

解决方法

以下博客包含一个完整的解决方案这个确切的问题.它实际上是一个非常优雅的解决方案,我强烈推荐.

https://blog.maartenballiauw.be/post/2010/01/26/translating-routes-(aspnet-mvc-and-webforms).html

注意让它适用于AREAs我不得不将以下扩展方法添加到他的“TranslatedRouteCollectionExtensions.cs”类中:

public static Route MapTranslatedRoute(this AreaRegistrationContext areaContext,string name,string url,object defaults,object routeValueTranslationProviders,bool setDetectedCulture)
    {
        TranslatedRoute route = new TranslatedRoute(
            url,new RouteValueDictionary(defaults),new RouteValueDictionary(routeValueTranslationProviders),setDetectedCulture,new MvcRouteHandler());

        route.DataTokens["area"] = areaContext.AreaName;

        // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up
        // controllers belonging to other areas
        bool useNamespaceFallback = (areaContext.Namespaces == null || areaContext.Namespaces.Count == 0);
        route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;

        areaContext.Routes.Add(route);

        return route;
    }

然而,即使是这样,一个具有AREA的翻译路由也可以被读取和解释,所生成的路由似乎总是包含一个英文的AREA名称,但本地化其他的一切.

我被引导到一个博客通过ASP.NET MVC Forums问同样的问题

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读