10

簡単な ASP.NET MVC バージョン 1.0 アプリケーションを作成しました。1 つのアクション インデックスを持つ ProductController があります。ビューで、対応する Index.aspx を Product サブフォルダーの下に作成しました。

次に、Spark dll を参照し、同じ Product ビュー フォルダーの下に Index.spark を作成しました。Application_Start は次のようになります

    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 コントローラーで Index アクションを参照するときに、Spark エンジンを使用し、他のすべての URL には WebFormViewEngine を使用する必要があります。

ただし、このテストでは、Product コントローラーの Index アクションも WebFormViewEngine を使用していることがわかります。

WebFormViewEnginer の登録 (コードの最後の行) をコメント アウトすると、Index アクションが Spark エンジンによってレンダリングされ、残りの URL がエラーを生成することがわかります (既定のエンジンがなくなったため)。スパークコードは正しいです。

私の質問は、ビューエンジンがどのように解決されるかです。登録シーケンスが有効にならないのはなぜですか?

4

2 に答える 2

19

ビュー エンジンを登録する順序は (あまり) 重要ではありません。むしろ、ビュー エンジンは のセットを取り、ViewLocationFormats特定のビュー パスがフォーマットされた名前に適合する場合、そのエンジンが使用されます。競合する形式がある場合にのみ、登録順序が重要になります。

スパークの場合、ビューには.spark拡張子が必要です。 または拡張子WebFormViewEngineの付いたものに応答します。そしてもちろん、前述のように、個々のビュー エンジンに提供されている を変更することで、これをオーバーライドできます。.aspx.ascxViewLocationFormats


更新しました:

SparkViewFactoryWebFormViewEngine(より具体的には、後者の派生元) の両方のソースを調べたところ、VirtualPathProviderViewEngineこの奇妙な動作が見られる理由がわかります。

まずFind、クラスのメソッドは次のViewEngineCollectionように機能します (簡略化)。

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

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

つまり、キャッシュされていないモードに頼る前に、どのエンジンでも常にキャッシュされたビューを見つけようとします。

個々のビュー エンジンがこれを実装する方法は、メソッドの 2 番目のオーバーロードであり、という名前の引数FindViewを取ります。booluseCache

ただし、ここですべてが奇妙にVirtualPathProviderViewEngineなります。 と は、引数SparkViewEngineが何を意味するかについて非常に異なる考えを持っています。useCacheここに再投稿するにはコードが多すぎますが、基本的な考え方は次のとおりです。

  • がの場合、はキャッシュのみSparkViewFactoryを検索します。何も見つからない場合は、自動的に「キャッシュ ミスの結果」が返されます。つまり、何も返されません。一方、isの場合、キャッシュをまったく検索せず、キャッシュ チェック ステップをスキップし、通常の動作を経て解決し、実際のビューを作成します。useCachetrueuseCachefalse

  • 一方VirtualPathProviderViewEngine、 は、 の場合useCacheはキャッシュtrueを調べ、キャッシュにビューが見つからない場合はオフになり、新しいビューを作成してキャッシュに追加します。

これらのアプローチは両方とも、 がViewEngineCollection検索を実行する方法に関して機能します。

  • スパークの場合、ビュー エンジンの最初の繰り返しでは「ミス」しますが、2 回目では「ヒット」し、その後ビューがキャッシュに追加されます。問題ない。

  • の場合、VirtualPathProviderViewEngine内部的に「ミス」しますが、最初の繰り返しで「ヒット」を返し、その時点でビューがキャッシュされます。

したがって、ここで問題がどこにあるかを確認できるはずです。前者は最初の(キャッシュされた) 反復で常に成功しますが、Spark は2 番目VirtualPathProviderViewEngineの (キャッシュされていない) 反復でのみ成功するため、のみよりも優先されるようです。SparkViewEngine

平易な英語で言えば、Spark は実際に最初に質問されますが、 「いいえ、まだそのビューを持っていません。代わりにキャッシュなしで試してみてください」と答えます。WebForms は 2 番目に尋ねられますが、自動的に「そのビューはありませんでしたが、とにかくあなたのために作成しました。ここにあります」と答えます。. その時点から、WebFormViewEngineキャッシュされたビューがあり、Spark がキャッシュされていないため、常に優先されます。


概要: SparkuseCache優先されていますが、Web フォーム エンジンが同時にアクティブになっていると、Spark の引数の処理方法に問題があるため、後回しになっています。あなたの視点に応じて、WebFormが過度に熱心であるか、Sparkが怠惰です。

簡単に言えば、解決策は意見が対立しないことです。 複数のビュー エンジンを登録した場合は、それらのいずれかまたは両方で処理できるビュー名を未定義の動作として扱う必要があります。

于 2010-03-08T03:49:39.293 に答える
1

うーん...いいえ-すべての正当なウェブフォームは、useCacheがtrueの場合、キャッシュチェックを超えて何もしません。スパークと同じ。

実際、誰かが私のチーズを動かしたのではないかと思います... Spark には、useCache==true パス中に偽のキャッシュミスを引き起こす癖が追加されている可能性があります。それが本当なら、そのパラメーターに適用されるさまざまなルールというよりもバグです。


更新しました:

私はもともとMVC 2を見ていました-それが@Aaronaughtの結論が間違っていることを暗示した理由です。MVC 2 は、useCache==true である最初のパスでビューを返しません。これは、解決して入力する MVC 1.0 とは異なります。

したがって、ASP.NET MVC 1.0 と ASP.NET MVC 2 の実装方法には違いがあります。Spark と MVC 2 は useCache フラグを同じように扱い、それらが登録された順序で優先されます。

于 2010-05-19T07:21:18.260 に答える