元]ASP.NET MVC 3 Razor多言語リファレンスソリューション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")
これでいいでしょう.入力が完了すると問題がおかしいことに気づきました.このコードの下でパラメータが一致していないことを教えてくれました.この2つのパラメータ、1つのHtml属性、1つの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()も正常に動作