[翻譯]ASP.NET MVC 3 開發的20個秘訣(四)[20 Recipes for Programming MVC 3]:實現多語言支援

來源:互聯網
上載者:User

議題

互連網上有數以百萬計來自數百個國家的人,同時也存在數百種不同的語言,甚至英國、美國、加拿大和英國之間也有多個不同的方言。不要讓你的網站因為只提供一種語言而被限制瀏覽。

解決方案

建立資源檔,並添加Key/Value類型的靜態文本,並實現CurrentUICulture以提供更改當前現實語言的能力。 

討論

資源檔是XML檔案,可以為網站儲存多國語言。當你建立一個資源檔時會包含當前預設語言。在資源中建立一個鍵/值對文本後,你就可以在控制器、模型和視圖中隨處使用了。例 1-3 資源檔樣本。

  

圖例 1-3,資源檔樣本

 

按右鍵應用程式,選擇“添加”->“建立檔案夾”,將新檔案命名為“Resources”。按右鍵新檔案夾,選擇“添加”->“建立項”。在後側搜尋中輸入“資源”並選擇“資源檔”。

如所示,我們在資源檔中建立“Book”模型類的所有屬性的條目。接下來我們需要修改模型類,使用DisplayAttribute引用這些值:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using MvcApplication4.Validations;

namespace MvcApplication4.Models
{

public class Book
{
public int ID { get; set; }

[Required]
[Display(Name = "TitleDisplay",
ResourceType = typeof(Resources.Resource1))]
public string Title { get; set; }

[Display(Name = "IsbnDisplay",
ResourceType = typeof(Resources.Resource1))]
[Required]
[IsbnValidation]
public string Isbn { get; set; }

[Display(Name = "SummaryDisplay",
ResourceType = typeof(Resources.Resource1))]
[Required]
public string Summary { get; set; }

[Display(Name = "AuthorDisplay",
ResourceType = typeof(Resources.Resource1))]
[Required]
public string Author { get; set; }

[Display(Name = "ThumbnailDisplay",
ResourceType = typeof(Resources.Resource1))]
public string Thumbnail { get; set; }

[Display(Name = "PriceDisplay",
ResourceType = typeof(Resources.Resource1))]
[Range(1, 100)]
public double Price { get; set; }

[Display(Name = "PublishedDisplay",
ResourceType = typeof(Resources.Resource1))]
[DataType(DataType.Date)]
[Required]
public DateTime Published { get; set; }

}

public class BookDBContext : DbContext
{
public DbSet<Book> Books { get; set; }
}

}

 

在上面這個例子中,DisplayAttribute使用鍵名欄位在資源檔中檢索引用相應的資源值。這樣的引用可以在每個視圖以及控制器上使用。

 

在接下來的例子中,我們將更改書籍索引檢視表的現實文本,將這些靜態文本移動到資源檔中。如表1-1建立鍵/值對錶:

鍵名

BookIndexTitle

索引

CreateLink

建立

EditLink

編輯

DetailsLink

詳情

DeleteLink

刪除

1-1 更新資源檔

 

目前為止只建立了一個資源檔,而其中所有的鍵名必須是整個項目唯一的。如你所見,在表中所建立的五個索引值對,在所有視圖中都可以連結使用。 

將資源檔更新完成後,開啟BooksController並使用下面的代碼替換Index()方法:

        //
// GET: /Books/
public ViewResult Index()
{

#region ViewBag Resources

ViewBag.Title =
Resources.Resource1.BookIndexTitle;

ViewBag.CreateLink =
Resources.Resource1.CreateLink;

ViewBag.TitleDisplay =
Resources.Resource1.TitleDisplay;

ViewBag.IsbnDisplay =
Resources.Resource1.IsbnDisplay;

ViewBag.SummaryDisplay =
Resources.Resource1.SummaryDisplay;

ViewBag.AuthorDisplay =
Resources.Resource1.AuthorDisplay;

ViewBag.ThumbnailDisplay =
Resources.Resource1.ThumbnailDisplay;

ViewBag.PriceDisplay =
Resources.Resource1.PriceDisplay;

ViewBag.PublishedDisplay =
Resources.Resource1.PublishedDisplay;

ViewBag.EditLink =
Resources.Resource1.EditLink;

ViewBag.DetailsLink =
Resources.Resource1.DetailsLink;

ViewBag.DeleteLink =
Resources.Resource1.DeleteLink;

#endregion

return View(db.Books.ToList());

}

 

最後,書籍的索引目錄檢視必須將所有的文本改為ViewBag相應屬性的引用:

@model IEnumerable<MvcApplication6.Models.Book>

<h2>@ViewBag.Title</h2>
<p>
@Html.ActionLink((string)ViewBag.CreateLink, "Create")
</p>

<table>
<tr>
<th>
@ViewBag.TitleDisplay
</th>

<th>
@ViewBag.IsbnDisplay
</th>

<th>
@ViewBag.SummaryDisplay
</th>

<th>
@ViewBag.AuthorDisplay
</th>

<th>
@ViewBag.ThumbnailDisplay
</th>

<th>
@ViewBag.PriceDisplay
</th>

<th>
@ViewBag.PublishedDisplay
</th>
<th></th>
</tr>

@foreach (var item in Model)
{

<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>

<td>
@Html.DisplayFor(modelItem => item.Isbn)
</td>

<td>
@Html.DisplayFor(modelItem => item.Summary)
</td>

<td>
@Html.DisplayFor(modelItem => item.Author)
</td>

<td>
@Html.DisplayFor(modelItem => item.Thumbnail)
</td>

<td>
@Html.DisplayFor(modelItem => item.Price)
</td>

<td>
@Html.DisplayFor(modelItem => item.Published)
</td>
<td>
@Html.ActionLink((string)ViewBag.EditLink,
"Edit", new { id = item.ID }) |

@Html.ActionLink((string)ViewBag.DetailsLink,
"Details", new { id = item.ID }) |

@Html.ActionLink((string)ViewBag.DeleteLink,
"Delete", new { id = item.ID })

</td>
</tr>
}

</table>

 

其他的視圖和控制器都可以通過這樣的方式修改,完成這些修改之後,我們只需要將資源檔複製成其他語言版本。

為了避免額外的輸入,建議程式完成,所有檔案都被添加到資源檔中。按右鍵當前資源檔點擊“複製”,然後,按右鍵“Resources”檔案夾點擊“粘貼”,並將複製所得的資源副本檔案重新命名為“Resource1.fr.resx”,當然,也可以以你所希望的語言建立並命名其他副本。然後將這檔案中的值得部分翻譯成你所希望的語言文本。

要根據請求來變化語言,必須在Global.asax.cs檔案的Appliation_AcquireRequestState()方法中通過改變每個請求的CurrentUICulture來實現:

       protected void Application_AcquireRequestState(
object sender, EventArgs e)
{

if (HttpContext.Current.Session != null)
{

CultureInfo ci =
(CultureInfo)this.Session["CurrentLanguage"];

if (ci == null)
{
ci = new CultureInfo("en");
this.Session["CurrentLanguage"] = ci;
}

Thread.CurrentThread.CurrentUICulture = ci;

Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(ci.Name);
}
}

在上面的程式碼範例中,經過檢測之後會將有效CultureInfo賦值給會話變數CurrentLanguage,如果為檢測到有效CultureInfo,系統會預設將英文賦予CurrentLanguage。接下來,我們會在Home控制器中建立一個動作,為使用者提供選擇語言的功能:

       

        public ActionResult ChangeLanguage(string language)
{
Session["CurrentLanguage"] =
new CultureInfo(language);

return Redirect("Index");
}

ChangeLanguage接受設定新語言名稱的參數,這個參數變數會更新Global.asax.cs中的繪畫變數,然後切換至使用者選中語言介面。將下面的連結添加到全域共用主版頁面_Layout.cshtml中:

[ @Html.ActionLink("English", "ChangeLanguage", "Home",
new { language = "en" }, null) ]

[ @Html.ActionLink("Français", "ChangeLanguage", "Home",
new { language = "fr" }, null) ]

我們將連結放置在“登入”連結的旁邊,這樣隨著網站的逐步發展,建立一個新的資源檔,添加一個新的連結,這樣使用者就可以選擇一種新的語言了,添加一種新語言非常容易。

在之前我們討論過加拿大、美國、英國等國家有和很多不同的英語方言,如果想為不同的國家添加語言資訊,可以在國家的代碼後面添加語言代碼,並通過字元“-”串連起來。例如,“en-GB”表示英國英語,添加之後還需要更新連結、語言名稱以及CurrentUICulture設定。

參考資訊

CurrentUICulture 原書地址 書籍原始碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.