为什么注册我的ViewEngines的顺序似乎并不重要

时间:2011-10-18 15:05:13

标签: asp.net-mvc-3

我编写了一个测试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之前创建视图时应该是什么?

1 个答案:

答案 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" });
}