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

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

假设您在 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());
于 2011-03-29T16:10:36.840 回答
1

或者,您可能可以使用我在此答案中描述的一些技术:如何更改 asp.net mvc 2 中的主题

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

于 2011-03-31T10:08:51.630 回答