2

写一个小的概念证明应用程序,想知道为什么 masterPath 参数是空的:

在 application_start 中:

ViewEngines.Engines.Add(new AlternateLocationViewEngine(
                new string[] { 
                    "~/Views/Shared/_Layout.cshtml", //Is this correct? Can/should i do that
                    "~/Views/Shared/{0}.cshtml",
                    "~/Plugins/Views/Shared/{0}.cshtml",
                },
                new string[] { 
                    "~/Plugins/Views/{1}/{0}.cshtml", 
                    "~/Plugins/{1}/{0}.chstml",    
                    "~/Plugins/Views/Shared/{0}.cshtml" 
                }
            ));




public class AlternateLocationViewEngine : RazorViewEngine 
    {
        public AlternateLocationViewEngine(string[] masterLocations, string[] viewLocations)
            : base()
        {
            MasterLocationFormats = masterLocations;
            ViewLocationFormats = viewLocations;
            PartialViewLocationFormats = ViewLocationFormats;

        }

        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
        {
            if (string.IsNullOrEmpty(masterPath))
            {               
                masterPath = MasterLocationFormats.ElementAt(0);
            }


            var nameSpace = controllerContext.Controller.GetType().Namespace;
            return base.CreateView(controllerContext, viewPath.Replace("%1", nameSpace), masterPath.Replace("%1", nameSpace));
        }
    }

如您所见,我被迫在 CreateView() 方法中检查 masterPath 是否为空。为什么是这样?我错过了一些基本的东西吗?

我的开发环境:ASP.NET MVC3、Razor、.NET4

4

1 回答 1

2

masterPath 只有在使用 masterName 创建 ViewResult 时才会有值。

protected internal ViewResult View(string viewName, string masterName);

在内部,RazorView 在其构造函数中处理 null masterPaths。

// where layoutPath is the masterPath arg from the RazorViewEngine's CreateView
LayoutPath = layoutPath ?? String.Empty;

渲染视图时,RazorView 会将 OverridenLayoutPath 设置为 masterPath(如果提供)。

// An overriden master layout might have been specified when the ViewActionResult got returned.
// We need to hold on to it so that we can set it on the inner page once it has executed.
webViewPage.OverridenLayoutPath = LayoutPath;

您不需要将 _Layout 指定为 MasterLocationFormat 之一。下面是 RazorViewEngine 的默认行为。

  MasterLocationFormats = new[] {
            "~/Views/{1}/{0}.cshtml",
            "~/Views/{1}/{0}.vbhtml",
            "~/Views/Shared/{0}.cshtml",
            "~/Views/Shared/{0}.vbhtml"
        };

您可以查看源代码以获得更多灵感。

于 2012-11-19T16:44:36.793 回答