有两种方法可以解决您的问题:
- 工作量更少 - 但重复性更高。
- 更多的工作,但排除了您喜欢的惯例。
减少工作量
对于任何ActionResult,您可以简单地在return 语句中添加第二个参数来指定要使用的master 的名称:
return View("Gallery", "Default");
第一个参数名称是视图,第二个表示母版页覆盖...但这确实意味着您需要在任何地方重复它,这并不比以前的更好。
更多工作
Spark 定位要使用的母版页的方式是通过框架中的以下代码:
protected virtual IEnumerable<string> PotentialDefaultMasterLocations(string controllerName, IDictionary<string, object> extra)
{
return ApplyFilters(new[]
{
"Layouts\\" + controllerName + ".spark",
"Shared\\" + controllerName + ".spark",
"Layouts\\Application.spark",
"Shared\\Application.spark"
}, extra);
}
请注意其中的硬编码 Application.spark - 这是 Spark 约定。您似乎想要做的是覆盖此方法并放入类似的内容:
protected virtual IEnumerable<string> PotentialDefaultMasterLocations(string controllerName, IDictionary<string, object> extra)
{
return ApplyFilters(new[]
{
"Layouts\\" + controllerName + ".spark",
"Shared\\" + controllerName + ".spark",
"Layouts\\Default.spark",
"Shared\\Default.spark"
"Layouts\\Application.spark",
"Shared\\Application.spark"
}, extra);
}
然后它会在找到Application.spark 之前找到您的Default.spark,或者如果它不适合您并且您更喜欢您的约定,您可以完全摆脱Application.spark...
为了覆盖它,您需要做的就是创建一个继承自Spark.Web.Mvc.DefaultDescriptorBuilder 的类并覆盖上面提到的该方法,并在您注册视图引擎时使用它,如下所示:
public static void RegisterViewEngine(ICollection<IViewEngine> engines)
{
var services = SparkEngineStarter.CreateContainer();
services.SetServiceBuilder<IDescriptorBuilder>(
c => new MyDescriptorBuilder());
SparkEngineStarter.RegisterViewEngine(services);
}
这意味着您现在可以指示 Spark 应在何处查找主视图以及名称将是什么。
希望对您有所帮助,
万事如意,
罗伯特·格雷