ASP.NET MVC 1的主题支持,获取视图主人名

时间:2011-03-29 15:19:21

标签: asp.net-mvc themes webforms-view-engine

目前我正在开发一个较旧的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";

始终由我自己让发动机工作。但是,由于我有几个主文件,一旦视图需要另一个主人而不是“站点”,这个解决方案很糟糕。 有谁知道,我如何在这个方法中获得主视图名称?

3 个答案:

答案 0 :(得分: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事件中处理主文件。

答案 1 :(得分:1)

解决了同样的问题,但方法略有不同。

假设您在Theme文件夹中有替代视图树,那么您必须在您的类中设置从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());

答案 2 :(得分:1)

或者,你可以使用我在这个答案中描述的一些技巧:how to change the themes in asp.net mvc 2

它在MVC3和Razor上,但除View之外的所有内容都应该在MVC 1上正常工作。