Asp.net mvc ASP.NET MVC视图引擎解析序列
我创建了一个简单的ASP.NET MVC 1.0版应用程序。我有一个ProductController,它有一个操作索引。在视图中,我在Product子文件夹下创建了相应的Index.aspx 然后,我引用了Spark dll并在同一产品视图文件夹下创建了Index.Spark。应用程序的启动看起来像Asp.net mvc ASP.NET MVC视图引擎解析序列,asp.net-mvc,spark-view-engine,viewengine,Asp.net Mvc,Spark View Engine,Viewengine,我创建了一个简单的ASP.NET MVC 1.0版应用程序。我有一个ProductController,它有一个操作索引。在视图中,我在Product子文件夹下创建了相应的Index.aspx 然后,我引用了Spark dll并在同一产品视图文件夹下创建了Index.Spark。应用程序的启动看起来像 protected void Application_Start() { RegisterRoutes(RouteTable.Routes); V
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new Spark.Web.Mvc.SparkViewFactory());
ViewEngines.Engines.Add(new WebFormViewEngine());
}
我的期望是,由于Spark引擎在默认WebFormViewEngine之前注册,因此在Product controller中浏览索引操作时,应使用Spark引擎,而WebFormViewEngine应用于所有其他URL
但是,测试表明Product controller的索引操作也使用WebFormViewEngine
如果我注释掉WebFormViewEnginer的注册(代码中的最后一行),我可以看到索引操作由Spark engine呈现,其余URL生成错误(因为defualt engine已消失),这证明我所有的Spark代码都是正确的
现在我的问题是如何解决视图引擎?为什么注册顺序不生效?注册视图引擎的顺序无关紧要。相反,视图引擎采用一组
ViewLocationFormats
,如果特定的视图路径符合格式化名称,则将使用该引擎。只有在格式冲突的情况下,注册顺序才重要
对于spark,视图应具有.spark
扩展名WebFormViewEngine
将使用.aspx
或.ascx
扩展名响应任何请求。当然,如上所述,您可以通过更改提供给各个视图引擎的ViewLocationFormats
来覆盖所有这些
更新: 我查看了
SparkViewFactory
和WebFormViewEngine
(或者更具体地说,VirtualPathProviderViewEngine
,后者的来源)的源代码,我可以告诉您为什么会看到这种奇怪的行为
首先,ViewEngineCollection
类中的Find
方法的工作原理如下(简化):
换句话说,它总是在任何引擎中尝试查找缓存视图,然后再求助于uncached模式
单个视图引擎实现这一点的方式是FindView
方法的第二个重载,该方法使用名为useCache
的bool
参数
然而,VirtualPathProviderViewEngine
和SparkViewEngine
对useCache
参数的含义有着截然不同的理解。这里有太多代码需要重新发布,但基本思想是:
- 如果
为useCache
,则true
将仅在缓存中查找。如果找不到任何内容,它会自动返回“缓存未命中结果”-即无。另一方面,如果SparkViewFactory
为useCache
,它将根本不在缓存中查找,它将跳过缓存检查步骤,并通过正常动作解析并创建实际视图false
- 另一方面,如果
为useCache
,则true
会在缓存中查找,如果在缓存中找不到视图,则会关闭并创建一个新视图,并将其添加到缓存中。VirtualPathProviderViewEngine
ViewEngineCollection
执行搜索的方式有关
- 对于spark,它在视图引擎的第一次迭代中“未命中”,但在第二次迭代中“命中”,然后将视图添加到缓存中。没问题
- 在
的情况下,它在内部“未命中”,但在第一次迭代时仍返回“命中”,此时视图现在被缓存VirtualPathProviderViewEngine
VirtualPathProviderViewEngine
似乎优先于SparkViewEngine
,因为前者总是在第一次(缓存)迭代中成功,而Spark只在第二次(未缓存)迭代中成功
用简单的英语说,Spark确实是第一个被问到的,但是回答:“不,我还没有那个视图,请在没有缓存的情况下试试。”WebForms被问到第二个问题,但自动说“我没有那个视图,但我还是去为你做了一个,在这里。”。从那时起,WebFormViewEngine
总是获得优先权,因为它缓存了视图,而Spark没有
小结:Spark正在获得优先级,但由于Spark处理
useCache
参数的方式有一个怪癖,当Web表单引擎同时处于活动状态时,它就被抛在了后面。WebForm要么过于急切,要么Spark懒惰,这取决于您的视角
简单地说,解决方案是不要有冲突的观点如果您注册了多个视图引擎,那么您应该将其中一个/两个可以处理的任何视图名称视为未定义的行为。。。不-当useCache为true时,所有应有的尊重webforms除了缓存检查之外不会做任何事情。和Spark一样 事实上,我想可能有人动了我的奶酪。。。Spark可能添加了一个怪癖,导致在useCache==true过程中出现错误缓存未命中。如果这是真的,那么它更像是一个bug,而不是应用于该参数的不同规则
更新: 我最初是在看MVC2,这就是为什么我暗示@Aaronaught的结论是不正确的。MVC 2在第一次传递时不返回useCache==true的视图,这与MVC 1.0中的不同,MVC 1.0将解析和填充该视图
foreach (IViewEngine engine in Items) {
// Query engine for cached view
}
foreach (IViewEngine engine in Items) {
// Query engine for uncached view
}