1

現在、テーマのサポートを追加するために、古い ASP.NET MVC 1 アプリケーションで開発しています。私はウェブを見回して、これまでうまく機能する独自の ViewEngine を構築することができました。唯一の問題は、私の持っていたものを叩くことです。

WebFormViewEngine の次のメソッドを上書きしました。

public override ViewEngineResult FindView(
    ControllerContext controllerContext, 
    string viewName, 
    string masterName, 
    bool useCache)

このメソッドでは、テーマ サポートの場所の形式を設定しています。残念ながら、masterName パラメータは常に空です。だから私はチェックする必要があります

if (string.IsNullOrEmpty(masterName))    
    masterName = "Site";

エンジンを動かすためにいつも一人で。しかし、私はいくつかのマスターファイルを持っているので、ビューが「サイト」以外の別のマスターを必要とするとすぐに、この解決策はうまくいきません。このメソッドでマスタービュー名を取得する方法を知っている人はいますか?

4

3 に答える 3

2

自力で解決しました。多くの調査の後、私は次のスニペットを見つけました。

private void RenderViewPage(ViewContext context, ViewPage page)
            {
                if (!String.IsNullOrEmpty(MasterPath)) {
                    page.MasterLocation = MasterPath;
                } else {
                    if (sc.WIP.CarharttIMD.Common.Config.GetStringValue("Theme") != "Default")
                        page.PreInit += new EventHandler(page_PreInit);
                }

                page.ViewData = context.ViewData;
                page.RenderView(context);
            }

void page_PreInit(object sender, EventArgs e)
            {
                ViewPage page = sender as ViewPage;
                //test for Default theme path, and replace with current theme
                string defaultthemepath = string.Format("{0}Content/Default", page.Request.ApplicationPath);
                if (!string.IsNullOrEmpty(page.MasterPageFile) && !page.MasterPageFile.ToLower().StartsWith(defaultthemepath.ToLower()))
                {
                    string masterPagePath = page.MasterPageFile;
                    int lastIndexOfSlash = masterPagePath.LastIndexOf('/');
                    string masterPageName = masterPagePath.Substring(lastIndexOfSlash + 1, masterPagePath.Length - lastIndexOfSlash - 1);
                    string newMaster = string.Format(
                        "~/Content/{0}/Views/Shared/{1}",
                        Common.Config.GetStringValue("Theme"),
                        masterPageName
                    );
                    if (File.Exists(page.Server.MapPath(newMaster)))
                        page.MasterLocation = newMaster;
                }
            }

WebViewForm をサブクラス化し、PreInit イベントでマスター ファイルを処理する必要がありました。

于 2011-03-31T08:11:50.283 に答える
1

同じ問題を解決しましたが、アプローチは少し異なりました。

テーマ フォルダーに別のビュー ツリーがあるとします。次に、WebFormViewEngine から派生したクラス MyViewEngine に設定する必要があります。

base.MasterLocationFormats =  new[] {
                        "~/Theme/Views/{1}/{0}.master", 
                        "~/Theme/Views/Shared/{0}.master"
                    }
                ).ToArray();

base.ViewLocationFormats = viewLocationFormats.Concat(
                    new[] {
                        "~/Theme/Views/{1}/{0}.aspx", 
                        "~/Theme/Views/Shared/{0}.aspx", 
                    }
                ).ToArray()

そしてメソッドをオーバーライドします:

protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
    return System.IO.File.Exists(controllerContext.HttpContext.Server.MapPath(virtualPath));
}

Global.asax.cs ファイルの Application_Start メソッドに次を追加します。

System.Web.Mvc.ViewEngines.Engines.Clear();
System.Web.Mvc.ViewEngines.Engines.Add(new WebFormThemeViewEngine());
于 2011-03-29T16:10:36.840 に答える
1

または、この回答で説明したテクニックのいくつかを使用することもできます: asp.net mvc 2 でテーマを変更する方法

これは MVC3 と Razor にありますが、View 以外はすべて MVC 1 でも問題なく動作するはずです。

于 2011-03-31T10:08:51.630 に答える