zoukankan      html  css  js  c++  java
  • [原]ASP.NET MVC 3 Razor 多国语言参考解决方案 补充四

    前四回(1,2,3,4)介绍了在ASP.NET MVC 3使用Razor ViewEngine时实现多国语言的解决方案,本以为就够用了,没料到今天居然在使用时又遇到新问题了。

    先说需求,最近做了一套全新的页面样式,基本思路是在iframe中显示内容,那么毫无疑问,这些内容页就是MVC的视图了,但是主页以何种形式存在呢?.html?.cshtml?.aspx?如果是.html的话,最主要的问题就是实现多图语言,服务器端不处理,难道使用js不成?而且不知道未来还会不会有必须服务器端参与处理的事情呢;.aspx我也不愿意,说实话,我不喜欢aspx那繁琐的生命周期,更不喜欢.aspx那种自以为是,老是替你作决定;于是决定使用.cshtml。

    在之前建的Website项目中,我发现能添加.cshtml的文件,那在MVC的项目中,想必也能使用单独的.cshtml来作页面了,于是新建一个.cshtml页面,把之前html页面复制进去,运行,发现果然如愿开启了页面,接下来把html中的占位符换成资源文件,如:

    <a href="#">欢迎: </a>
    

    换成

    @Html.Lang("Welcome")
    

    但是发现Html下面居然没有Lang扩展方法,在我的记忆中,view中输入@Html,自动完成列表中就会出现Lang方法了,为啥不行呢,扩展方法出不来的第一原因就是没有引入命名空间,于是在文件最上面加入

    @using System.Web.Mvc
    

    但是还是不行,想想也不行,@Html都有了,没有理由不出现扩展方法啊, 要么换一种方法调用,直接调用静态方法:

    @LocalizationHelper.Lang(Html, "Welcome")
    

    这下总行了吧,结果输入完成就发现问题不对劲了,这行代码下居然告诉我参数不匹配,就这么两个参数,一个Html属性,一个string,居然还不对,看了半天没有看出端倪,干脆我让VS自动生成匹配的方法,到底是啥样的方法签名,结果这一生成终于发现问题所在了:

            public static object Lang(WebPages.Html.HtmlHelper htmlHelper, string p)
            {
                throw new NotImplementedException();
            }
    

    这个HtmlHelper的命名空间是WebPages.Html,而我之前定义的方法中参数HmtlHelper的命名空间是System.Web.Mvc!怪不得呢,原来不是一个东西啊,看起来使用RazorEngine时,视图和页面不是同一种类型

    本打算那就使用这个HtmlHelper类型当参数吧,又发现这个类型中只有一些辅助方法,没有Request、Response、Server之类的对象实例,基于我在Lang方法内部是需要请求详细信息的,于是我打算使用将页面本身(WebPageBase)作为参数,于是修改为下面的样子:

    public static string Lang(this WebPageBase page, string key)
    {
    }
    

    接下来就是重构,最终LocalizationHelper变成了下面的样子:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using CleverSoft.WebUtil;
    using System.Runtime.Caching;
    using System.Resources;
    using System.Collections;
    using System.Web.WebPages;
    
    namespace System.Web.Mvc
    {
        public static class LocalizationHelper
        {
            public static string Lang(this HtmlHelper htmlhelper, string key)
            {
                return Lang(htmlhelper.ViewDataContainer as WebViewPage, key);
            }
    
            private static IEnumerable<DictionaryEntry> GetResx(string resxKey)
            {
                ObjectCache cache = MemoryCache.Default;
    
                IEnumerable<DictionaryEntry> resxs = null;
    
                if (cache.Contains(resxKey))
                {
                    resxs = cache.GetCacheItem(resxKey).Value as IEnumerable<DictionaryEntry>;
                }
                else
                {
                    if (File.Exists(resxKey))
                    {
                        resxs = new ResXResourceReader(resxKey).Cast<DictionaryEntry>();
                        cache.Add(resxKey, resxs, new CacheItemPolicy() { Priority = CacheItemPriority.NotRemovable });
                    }
                }
    
                return resxs;
            }
    
            public static string Lang(this WebPageBase page, string key)
            {
                var pagePath = page.VirtualPath;
                var pageName = pagePath.Substring(pagePath.LastIndexOf('/'), pagePath.Length - pagePath.LastIndexOf('/')).TrimStart('/');
                var filePath = page.Server.MapPath(pagePath.Substring(0, pagePath.LastIndexOf('/') + 1)) + "App_LocalResources";
                var langs = page.Request.UserLanguages != null ?
                    page.Request.UserLanguages.Union<string>(new string[] { "" }).ToArray<string>() : new string[] { "" };
    
                IEnumerable<DictionaryEntry> resxs = null;
    
                foreach (var lang in langs)
                {
                    var resxKey =
                        string.IsNullOrWhiteSpace(lang) ? string.Format(@"{0}\{1}.resx", filePath, pageName) : string.Format(@"{0}\{1}.{2}.resx", filePath, pageName, lang);
    
                    resxs = GetResx(resxKey);
    
                    if (resxs != null) { break; }
                }
    
                return (string)resxs.FirstOrDefault<DictionaryEntry>(x => x.Key.ToString() == key).Value;
            }
        }
    }
    

    最终在Razor页面使用

    @this.Lang("Welcome")
    

    终于出现结果了

    最终经过测试,在视图中使用@Html.Lang()也正常工作

  • 相关阅读:
    Linux kernel 拒绝服务漏洞
    WordPress Checkout插件跨站脚本漏洞和任意文件上传漏洞
    SpringMVC指定webapp的首页
    maven-jetty插件配置时,webdefault.xml的取得和修改
    pom.xml报错 : Missing artifact org.apache.shiro:shiro-spring:bundle:1.2.5
    maven+SSM+junit+jetty+log4j2环境配置的最佳实践
    “不让工具类能够实例化”的做法是适合的
    静态域/域的初始化、静态代码块/构造代码块的实行、构造方法的调用 顺序
    Java Collection Framework 备忘点
    JVM备忘点(1.8以前)
  • 原文地址:https://www.cnblogs.com/think8848/p/2098464.html
Copyright © 2011-2022 走看看