ASP.NET MVC视图引擎高分辨率层序 [英] ASP.NET MVC View Engine Resolution Sequence

查看:140
本文介绍了ASP.NET MVC视图引擎高分辨率层序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个简单的ASP.NET MVC 1.0版的应用程序。我有一个动作一个指数ProductController的。在视图中,我创建了下产品的子文件夹对应的Index.aspx。

I created a simple ASP.NET MVC version 1.0 application. I have a ProductController which has one action Index. In the view, I created a corresponding Index.aspx under Product subfolder.

然后,我引用的DLL星火和相同的产品视图文件夹下创建Index.spark。在的Application_Start看起来像

Then I referenced the Spark dll and created Index.spark under the same Product view folder. The Application_Start looks like

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);

        ViewEngines.Engines.Clear();
        ViewEngines.Engines.Add(new Spark.Web.Mvc.SparkViewFactory());

        ViewEngines.Engines.Add(new WebFormViewEngine());

    }

我的期望是,由于默认WebFormViewEngine前的星火引擎寄存器,当浏览产品控制器Index操作,星火引擎应该被使用,WebFormViewEngine应该用于其他所有网址。

My expectation is that since the Spark engine registers before default WebFormViewEngine, when browse the Index action in Product controller, the Spark engine should be used, and WebFormViewEngine should be used for all other urls.

然而,测试表明,对于产品控制器Index操作也使用WebFormViewEngine。

However, the test shows that the Index action for Product controller also uses the WebFormViewEngine.

如果我注释掉WebFormViewEnginer(在code中的最后一行)的登记,我可以看到,指数的行动是由星火引擎渲染,其余的URL生成一个错误(因为defualt引擎消失) ,它证明了我所有的星火code是正确的。

If I comment out the registration of WebFormViewEnginer (the last line in the code), I can see that the Index action is rendered by Spark engine and the rest urls generates an error (since the defualt engine is gone), it proves that all my Spark code is correct.

现在我的问题是如何在视图引擎得到解决?为什么注册序列不生效?

Now my question is how the view engine is resolved? Why the registration sequence does not take effect?

推荐答案

在您注册的视图引擎无关紧要(远)的顺序。相反,视图引擎采取了一套 ViewLocationFormats 的,如果一个特定视图路径适合的格式名称,该引擎将被使用。只有当你有冲突的格式不注册顺序问题。

The order in which you register the view engines doesn't matter (much). Rather, view engines take a set of ViewLocationFormats, and if a particular view path fits the formatted name, that engine will be used. Only if you have conflicting formats does the registration order matter.

在火花的情况下,意见应该有 .spark 扩展。 WebFormViewEngine 将任何与的.aspx 响应或的.ascx 扩展。当然,正如上面提到的,你可以通过改变覆盖任何这样做的 ViewLocationFormats 供给单独视图引擎。

In the case of spark, views should have the .spark extension. WebFormViewEngine will respond to any with .aspx or .ascx extensions. And of course, as mentioned above, you can override any of this by changing the ViewLocationFormats supplied to the individual view engines.

更新:

我把通过两个 SparkViewFactory WebFormViewEngine (或者更具体地说,<$ C $的来源看C> VirtualPathProviderViewEngine ,后者从提炼出来),我可以告诉你为什么你看到这种奇怪的行为。

I took a look through the source of both SparkViewFactory and WebFormViewEngine (or more specifically, VirtualPathProviderViewEngine, which the latter derives from), and I can tell you why you're seeing this strange behaviour.

首先,在查找 ViewEngineCollection 类方法的工作原理是这样(简体):

First of all, the Find method in the ViewEngineCollection class works like this (simplified):

foreach (IViewEngine engine in Items) {
    // Query engine for cached view
}

foreach (IViewEngine engine in Items) {
    // Query engine for uncached view
}

在换句话说,它总是试图诉诸未缓存模式之前找到一个缓存的视图中的任何引擎。

In other words, it will always try to find a cached view, in any engine, before resorting to uncached mode.

在单个视图引擎实现,这是 FindView 方法的第二个重载,这需要一个布尔参数名为 useCache将

The way in which individual view engines implement this is the second overload of the FindView method, which takes a bool argument named useCache.

然而,这里是在这一切会很奇怪 - 在 VirtualPathProviderViewEngine SparkViewEngine 拥有的 useCache将参数的意思完全不同的想法。有太多的code到这里重新发布,但基本思路是:

However, and here's where it all gets weird - the VirtualPathProviderViewEngine and SparkViewEngine have very different ideas of what the useCache argument means. There's too much code to repost here but the basic idea is:


  • SparkViewFactory 会看的在缓存中,如果 useCache将真正。如果没有发现任何,它会自动返回一个缓存未命中的结果 - 即什么都没有。在另一方面,如果 useCache将,也不会在缓存中看到的是,它会跳过缓存的检查步骤,并通过正常的运动来解决,并创建一个实际的看法。

  • The SparkViewFactory will look only in the cache if useCache is true. If it doesn't find anything, it automatically returns a "cache miss result" - i.e. nothing. On the other hand, if useCache is false, it will not look in the cache at all, it will skip the cache-checking step and go through the normal motions to resolve and create an actual view.

VirtualPathProviderViewEngine ,而另一方面,看上去在缓存中,如果 useCache将真正,如果它没有找到在缓存中的观点,它熄灭,并创建一个新的,并补充说,到缓存中。

The VirtualPathProviderViewEngine, on the other hand, looks in the cache if useCache is true, and if it doesn't find the view in the cache, it goes off and creates a new one and adds that to the cache.

这两种方法相对于工作方式的 ViewEngineCollection 执行其搜索。

Both of these approaches work with respect to the way ViewEngineCollection performs its search.


  • 在火花的情况下,上视图引擎的第一次迭代,但在第二次命中,并且该视图被添加到高速缓存之后未命中。没问题。

  • In the case of spark, it "misses" on the first iteration of view engines, but "hits" on the second, and after that the view is added to the cache. No problem.

VirtualPathProviderViewEngine 的情况下,未命中在国内,而且会返回一个打反正在第一次循环,此时的看法,这就是缓存

In the case of VirtualPathProviderViewEngine, it "misses" internally but returns a "hit" anyway on the first iteration, at which point the view is now cached.

所以,你应该能够看到那里的问题是在这里。在 VirtualPathProviderViewEngine 唯一的出现的是采取precedence在 SparkViewEngine ,因为前者总是成功的第一(缓存)迭代,但仅Spark成功的第二(非高速缓存)的迭代。

So you should be able to see where the problem is here. The VirtualPathProviderViewEngine only appears to be taking precedence over the SparkViewEngine because the former always succeeds on the first (cached) iteration, but Spark only succeeds on the second (uncached) iteration.

在简单的英语,星火确实先被问过,但回复:不,我没有这种观点的尚未尝试没有缓存代替。的WebForms被问第二位,但自动说的我没有有一个观点,但我去了,反正做了一个对你来说,在这儿呢。的。而从这一点上来说,在 WebFormViewEngine 总是获得优先权,因为它有观点缓存和Spark没有。

In plain English, Spark really does get asked first, but replies: "No, I don't have that view yet. Try it without the cache instead." WebForms gets asked second, but automatically says "I didn't have that view, but I went and made one for you anyway, here it is.". And from that point on, the WebFormViewEngine always gets priority because it has the view cached and Spark doesn't.

摘要:星火获得优先权,但由于方式星火一个怪癖对待 useCache将的说法,这是越来越抛在后面当Web表单发动机是活跃的同时。无论是WebForm的过于急切或Spark是懒惰的,取决于你的观点。

Summary: Spark is getting priority, but due to a quirk in the way Spark treats the useCache argument, it's getting left in the dust when the Web Form engine is active at the same time. Either WebForm is over-eager or Spark is lazy, depending on your perspective.

简单地说,解决的办法是的不要有冲突的观点!如果您已经注册了多个视图引擎,那么你应该处理这可以通过/处理两者的任何视图名称未定义行为

Simply put, the solution is not to have conflicting views! If you've registered multiple view engines, then you should be treating any view name which can be handled by either/both of them as undefined behaviour.

这篇关于ASP.NET MVC视图引擎高分辨率层序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆