欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET MVC的Localization本地化多语言支持

程序员文章站 2023-12-18 23:20:10
一、asp.net mvc的本地化支持 asp.net mvc的是基于asp.net运行,所以由asp.net提供的所有功能,都可以在mvc里使用,例如缓存,会话状态和本...

一、asp.net mvc的本地化支持

asp.net mvc的是基于asp.net运行,所以由asp.net提供的所有功能,都可以在mvc里使用,例如缓存,会话状态和本地化。 在传统的asp.net web窗体时代我们使用资源文件存储不同语言中的内容和使用由visual studio自动生成的resourcemanager类来检索它们。在asp.net mvc他们一样有效的。

让我创建一个标准的asp.net mvc的一个示例应用程序。该网站是中文的,我们可以看到所有的内容都是在视图和控制器类里写死的。

我使用的框架是mvc3的基于razor模板的网站。

使用visual studio 2010 创建 mvc3的web应用程序,在随后出现的选择中选择internet 应用程序,视图引擎为razor;

ASP.NET MVC的Localization本地化多语言支持

可以看出来现在网站是中文的,而且我们可以看到所有的内容在视图和控制器里都是硬编码的。

现在我需要做的是把所有的内容从页面和控制器里分离出来,asp.net给我们一个名为app_globalresources的文件,它里面包含各种语言的全局资源文件。我们只需要在解决方案管理器里的web项目上右击鼠标,添加->添加至asp.net文件夹->app_globalresources

ASP.NET MVC的Localization本地化多语言支持

我创建了中文、英文两个语言的资源文件,中文是程序的默认语言,所以我先创建global.resx文件,然后是global.en.resx,中间的“en”是英语的culture name。如果你需要法语,那么你只需要再创建global.fr.resx文件,visual studio会自动生成对应的类。

ASP.NET MVC的Localization本地化多语言支持

现在让我在资源文件里添加一些内容,在主页上我们需要替换三处:标题、消息还有描述,所以我们在这两个资源文件里添加3个项。

ASP.NET MVC的Localization本地化多语言支持

标题和描述都在视图页面里定义了,所以我将更改视图。

复制代码 代码如下:

@{
    viewbag.title = resources.global.home_index_title;
}
<h2>@viewbag.message</h2>
<p>
@resources.global.home_index_desc
<a href="" title="@resources.global.home_index_desclink">http://asp.net/mvc</a>。
</p>

复制代码 代码如下:

public actionresult index()
{
    viewbag.message = resources.global.home_index_message;
 
    return view();
}

二、通过url指定语言

我们已经把内容转移到了资源文件,但是我们的程序还不支持本地化,因为没有任何地方我们可以设置指定语言的地方。为了简单起见,我们将使用url来标明选择使用的语言(就类似微软网站),意思就是如果我的url是http://localhost/en-us/home/index ,则网站会体现为英文;而http://localhost/zh-cn/home/index 则是简体中文。用户可以在任何停留的页面更改语言,而且 当他想共享网址的时候也会保留语言设置。

为了达到效果,我更改了程序的路由,在最前头新增一个名为“lang”的路由规则:

复制代码 代码如下:

public static void registerroutes(routecollection routes)
{
    routes.ignoreroute("{resource}.axd/{*pathinfo}");
    routes.maproute(
        "localization", // 路由名称
        "{lang}/{controller}/{action}/{id}", // 带有参数的 url
        new { controller = "home", action = "index", id = urlparameter.optional }//参数默认值
        );
    routes.maproute(
        "default", // 路由名称
        "{controller}/{action}/{id}", // 带有参数的 url
        new { controller = "home", action = "index", id = urlparameter.optional } // 参数默认值
    );
}

要注意,代码里并没有设置lang的默认值,而且没有删除默认的路由,这个是为了防止如 and http://localhost/home/index之类地址时程序无法解析。

因为我们需要url设置语言,所以我们需要在每个action执行前执行写逻辑处理,这里actionfilter将是个不错的解决方案。

复制代码 代码如下:

using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.web.mvc;
using system.threading;
using system.globalization;
 
namespace shaunxu.mvclocalization
{
    public class localizationattribute : actionfilterattribute
    {
        public override void onactionexecuting(actionexecutingcontext filtercontext)
        {
            if (filtercontext.routedata.values["lang"] != null &&
                     !string.isnullorwhitespace(filtercontext.routedata.values["lang"].tostring()))
            {
                ///从路由数据(url)里设置语言
                var lang = filtercontext.routedata.values["lang"].tostring();
                thread.currentthread.currentuiculture = cultureinfo.createspecificculture(lang);
            }
            else
            {
                ///从cookie里读取语言设置
                var cookie = filtercontext.httpcontext.request.cookies["shaunxu.mvclocalization.currentuiculture"];
                var langheader = string.empty;
                if (cookie != null)
                {
                    ///根据cookie设置语言
                    langheader = cookie.value;
                    thread.currentthread.currentuiculture = cultureinfo.createspecificculture(langheader);
                }
                else
                {
                    ///如果读取cookie失败则设置默认语言
                    langheader = filtercontext.httpcontext.request.userlanguages[0];
                    thread.currentthread.currentuiculture = cultureinfo.createspecificculture(langheader);
                }
                ///把语言值设置到路由值里
                filtercontext.routedata.values["lang"] = langheader;
            }
 
            /// 把设置保存进cookie
            httpcookie _cookie = new httpcookie("shaunxu.mvclocalization.currentuiculture", thread.currentthread.currentuiculture.name);
            _cookie.expires = datetime.now.addyears(1);
            filtercontext.httpcontext.response.setcookie(_cookie);
 
            base.onactionexecuting(filtercontext);
        }
    }
}

我创建了一个继承自actionfilterattribute的"localizationattribute"并重写了onactionexecuting方法的属性,首先检查路由里的值,如果包含了语言设置,则设置当前进程的当前区域值,它指示资源管理器(visual studio根据资源文件自动生成)获取相关的值。如果找不到路由里的语言值,则读取cookie值来设置,否则使用默认语言。最后把值放进路由,并保存到cookie里。

我在home控制器里使用这个属性这样所有action都可以执行我的本地化逻辑。

复制代码 代码如下:

using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.web.mvc;
using showlocal.models;
 
namespace showlocal.controllers
{
    [localization]
    public class homecontroller : controller
    {
        public actionresult index()
        {
            viewbag.message = resources.global.home_index_message;
            return view();
        }
 
        public actionresult about()
        {
            return view();
        }
    }
}

选择我们可以启动网站然后添加语言在url上看看结果

ASP.NET MVC的Localization本地化多语言支持

上一篇:

下一篇: