我编写了一个测试ViewEngine,它响应视图名称为“About”的请求,并将以下内容添加到Application_Start
中的Global.asax
方法。
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());
ViewEngines.Engines.Add(new MyViewEngine());
FindView
的{{1}}方法如下:
MyViewEngine
当Home控制器响应关于的操作时,我原本希望if (viewName == "About")
return new ViewEngineResult(new MyView(), this);
return new ViewEngineResult(new List<string>{"Some arbitrary search location"});
处理RazorViewEngine
的请求(因为它首先添加到~/Home/About
集合中)但是它是不是...... Engines
正在处理对该网址的调用。
导致视图未命名为“关于”的调用由Razor正确处理。
即使我颠倒了上面两个MyViewEngine
语句的顺序,我也会得到完全相同的行为。如果我注释掉注册我的视图引擎的代码,Razor会按照我的预期选择Add
。
任何想法为什么~/Home/About
在Razor之前创建视图时应该是什么?
答案 0 :(得分:1)
ASP.NET MVC按预期在注册顺序中询问已注册的ViewEngines
。但是有一个问题。它位于ViewEngineCollection
FindView
方法中:
public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName)
此方法遍历可用的ViewEngines
请求视图,但它会执行两次。在使用FindView
调用useCache=true
方法时,如果ViewEngines
没有提供结果,则会再次使用useCache=false
对其进行迭代。
因此,在您询问RazorViewEngine
useCache=true
的情况下,它不会返回视图,因为没有chached的视图。但是您的视图引擎始终会提供View
。因此,您需要在实现中处理useCache=true
案例:
public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
if (useCache)
return new ViewEngineResult(new List<string> { "Not in cache" });
if (viewName == "About")
return new ViewEngineResult(new MyView(), this);
return new ViewEngineResult(new List<string> { "Some arbitrary search location" });
}