MVC 
▌目的
| 
l  實作一Website,由Routing rule(路由規則) 判斷目前網頁之語系。  
l  顯示之語系規則順序如下: 
(1)    
  Cookie 
(2)    
  URL (Routing rule) 
(3)    
  Browser default localization setting 
由Routing rule控制語系的好處在於 … 使用者可任意切換各種語系來做觀看,而不必去更動瀏覽器的設定。 
▋延伸閱讀 
▌環境 
l   Windows 7 Enterprise 
l   Visual Studio 2013
  update 5 
l   MVC 5 | 
▌實作
▋Routing Rule 
因為本文章的首要目標是以Routing rule判斷使用者瀏覽的語系,所以第一件事情是更新預設的Routing rule.
| 
routes.MapRoute( 
       name:
  "Default", // Route name 
       url:
  "{lang}/{controller}/{action}/{id}", // URL with
  parameters 
       defaults:
  new { lang = "Default", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter
  defaults 
       namespaces
  :  new[] { "JB.Sample.MultiLangWeb.Website.Controllers" } 
); | 
▋UI 
以下圖之UI 為範例。
l   _Layout.cshtml
| 
<div class="navbar-collapse
  collapse"> 
                <ul class="nav navbar-nav"> 
                    <li>@Html.ActionLink("首頁", "Index", "Home")</li> 
                    <li>@Html.ActionLink("關於", "About", "Home")</li> 
                    <li>@Html.ActionLink("連絡方式", "Contact", "Home")</li> 
                    @if (ViewBag.Lang == "ZH") 
                    { 
                        <li> 
                            <a href="~/CN" onclick="Redirect('CN')">簡體中文</a> 
                        </li> 
                        <li> 
                            <a href="~/EN" onclick="Redirect('EN')">英文</a> 
                        </li> 
                    } 
                    else if (ViewBag.Lang == "EN") 
                    { 
                        <li> 
                            <a href="~/ZH" onclick="Redirect('ZH')">Traditional
  Chinese</a> 
                        </li> 
                        <li> 
                            <a href="~/CN" onclick="Redirect('CN')">Simplified Chinese</a> 
                        </li> 
                    } 
                    else if (ViewBag.Lang == "CN") 
                    { 
                        <li> 
                            <a href="~/ZH" onclick="Redirect('ZH')">繁体中文</a> 
                        </li> 
                        <li> 
                            <a href="~/EN" onclick="Redirect('EN')">英文</a> 
                        </li> 
                    } 
                </ul> 
</div> | 
當點選語言時,Post back 設定Cookie並做轉址。
所以需要在後端Controller加上一Http Post method 並加上Ajax.
▋Controller : Http Post Method 
| 
[HttpPost] 
 public HttpResponseMessage SetLocaleCookie(string locale) 
 { 
            try 
            { 
                HttpCookie cultureCookie = Request.Cookies["_culture"]; 
                if (cultureCookie != null) 
                { 
                    cultureCookie.Value =
  locale; 
                } 
                else 
                { 
                    cultureCookie = new HttpCookie("_culture"); 
                    cultureCookie.HttpOnly = true; 
                    cultureCookie.Value =
  locale; 
                    //cultureCookie.Expires =
  DateTime.Now.AddMonths(2); 
                } 
                Response.Cookies.Add(cultureCookie); 
            } 
            catch (Exception ex) 
            { 
            } 
            return new HttpResponseMessage(HttpStatusCode.OK); 
} | 
▋Javascript 
| 
function Redirect(locale)
  { 
    var postUrl = "Default/Home/SetLocaleCookie"; 
    $.ajax({ 
        url: postUrl, 
        type: "POST", 
        data: JSON.stringify({ locale }), 
        contentType: 'application/json; charset=utf-8', 
        dataType: "json", 
        //timeout: 10000, 
        success: function (data, status) { 
        }, 
        error: function (jqXHR, textStatus, err) { 
        } 
    }); 
} | 
到目前為止,我們已經可以讓使用者自由的設定網站的語系Cookie。
下一步,我們要在網站首頁 (例如本例的本機開發網址  http://localhost:2609/ ) 判斷要導向到哪個語系的網址。
▋Home Controller  
由以上程式碼可知道本例支援的語系為:
ü   繁中:http://localhost:2609/ZH
ü   簡中:http://localhost:2609/CN
ü   簡中:http://localhost:2609/EN
判斷邏輯(順序):
(1)    
Cookie
(2)    
URL (Routing rule)
(3)    
Browser default localization setting
| 
public class HomeController : Controller 
{ 
     public ActionResult Index() 
     { 
            string lang =
  HttpContext.Request.RequestContext.RouteData.Values["lang"].ToString(); 
            ViewBag.Lang = lang; 
            //判斷是否須轉址 (以使用者的瀏覽器語言設定為主) 
            if (lang.Equals("Default")) 
            { 
                string redirectUri =
  getRedirectUri(lang); 
                if (!string.IsNullOrEmpty(redirectUri)) 
                { 
                    return Redirect(redirectUri); 
                } 
            } 
            return View(); 
     } 
private string getRedirectUri(string locale) 
{ 
            string redirectUri = string.Empty; 
            HttpCookie cultureCookie = Request.Cookies["_culture"]; 
            //若已設定Cookie則以Cookie為主  
            if (cultureCookie != null)  //已設定Culture Cookie,則以Cookie為主 
            { 
                locale = cultureCookie.Value; 
            } 
            //若未設定Cookie且未指定網頁語系,則以瀏覽器預設語系為主 
            else if (string.IsNullOrEmpty(locale) ||
  locale.Equals("Default")) 
            { 
                //取得用戶端語言喜好設定(已排序的字串陣列) 
                var userLanguages =
  Request.UserLanguages; 
                if (userLanguages.Length > 0) 
                { 
                    try 
                    { 
                        string userLang =
  userLanguages[0]; 
                        switch
  (userLang.ToLower()) 
                        { 
                            case "en-us": 
                                locale = "EN"; 
                                break; 
                            case "zh-cn": 
                                locale = "CN"; 
                                break; 
                            case "zh-tw": 
                            default: 
                                locale = "ZH"; 
                                break; 
                        } 
                    } 
                    catch (CultureNotFoundException ex) 
                    { 
                        //Do something 
                    } 
                } 
            } 
            else //已指定網頁語系 
            { 
                //Do nothing 
            } 
            //Redirect 
            try 
            { 
                switch (locale.ToUpper()) 
                { 
                    case "EN": 
                        redirectUri = "/EN"; 
                        break; 
                    case "CN": 
                        redirectUri = "/CN"; 
                        break; 
                    case "ZH": 
                    default: 
                        redirectUri = "/ZH"; 
                        break; 
                } 
                return redirectUri; 
            } 
            catch (Exception) 
            { 
                throw; 
            } 
     } 
} | 
▌測試
▌Reference



 
沒有留言:
張貼留言