11

ASP.NET MVC をいじっていて、質問がありました。あるいは、私がこれを間違っているのではないかと心配しているのかもしれません。私の翼を少し伸ばすために、不自由なサイトに取り組んでいます。申し訳ありませんが、この質問はまったく簡潔ではありません。

よし、これがシナリオだ。ユーザーがホーム/インデックスにアクセスすると、ページには製品のリストと記事のリストが表示されます。ファイルレイアウトは次のとおりです(DALは私のデータアクセスレイヤーです):

コントローラー
    家
        索引       

ビュー
    家
        インデックスは ViewPage から継承します
    製品         
        List は ViewUserControl<IEnumerable<DAL.Product>> から継承します
        シングルは ViewUserControl<DAL.Product> から継承します
    論文
        List は ViewUserControl<IEnumerable<DAL.Article>> から継承します
        シングルは ViewUserControl<DAL.Article> から継承します
Controllers.HomeController.Index produces a View whose ViewData contains two entries, a IEnumerable<DAL.Product> and a IEnumerable<DAL.Article>.

View.Home.Index will use those view entries to call:
Html.RenderPartial("~/Views/Product/List.ascx", ViewData["ProductList"])
and Html.RenderPartial("~/Views/Article/List.ascx", ViewData["ArticleList"])

View.Product.List will call
foreach(Product product in View.Model)
    Html.RenderPartial("Single", product);

View.Article.List does something similar to View.Product.List

ただし、このアプローチは失敗します。このアプローチは私には理にかなっていますが、これらの MVC プラットフォームの経験が豊富な人なら、より良い方法を認識するでしょう。

上記は、View.Product.List 内でエラーを生成します。Html.RenderPartial("Single",...)「Single」ビューが見つからなかったと不平を言う呼び出し。エラーは次のことを示しています。

部分ビュー 'Single' が見つかりませんでした。次の場所が検索されました。
~/Views/Home/Single.aspx
~/Views/Home/Single.ascx
~/Views/Shared/Single.aspx
〜/Views/Shared/Single.ascx

Product のビューから RenderAction() を呼び出していたので、ランタイムが Views\Product 内の "Single" ビューを探すことを期待していました。ただし、ルックアップは、現在のビューではなく、元のビュー (/Controller/Home によって呼び出された /Views/Product) を呼び出したコントローラーに関連しているようです。

したがって、次のように Views\Product を変更することでこれを修正できます。

View.Product.List will call
foreach(Product product in View.Model)
    Html.RenderPartial("~/Views/Product/Single.ascx", product);

それ以外の

View.Product.List will call
foreach(Product product in View.Model)
    Html.RenderPartial("Single", product);

この修正は機能しますが、ビューのフル パスを指定する必要がある理由がわかりません。相対名が元のコントローラーのビュー パスではなく、現在のビューのパスに対して相対的に解釈されることは、私には理にかなっています。現在のビューではなく、コントローラーのビューに関連する名前を解釈することが役立つ便利なケースは考えられません (それらが同じである典型的なケースを除いて)。

この頃、私はクエスチョンマークを持っているべきですか?これを強調することは、実際には問題です。

4

3 に答える 3

5

Product のビューから RenderAction() を呼び出していたので

...

ビューのフル パスを指定する必要がある理由がわかりません。元のコントローラーのビューパスではなく、現在のビューのパスに対して相対名が解釈されることは私には理にかなっています

あなたが誤解していると思う部分は、より良いまたは公式の用語がないための「実行場所」です。パスは、あなたが言う「コントローラーのビュー」でさえも、あなたのビューに相対的ではありません。これらは、コントローラー コンテキストを定義するリクエスト URL に相対的です。うまく言えないかもしれませんが、Reflector で URL とルートがどのように解決されるかを少し調べてみれば、すべてが頭の中に収まると思います。

于 2008-11-11T20:33:07.970 に答える
4

[編集:

私は考えていました、あなたには2つのケースがあります:

  • Home コントローラーは、Product / Articles List ユーザー コントロールを参照する唯一のコントローラーです。
  • ユーザーコントロールは複数のコントローラーで共有されています

最初のケースでは、ビュー ユーザー コントロールは実際にはホーム コントローラーに属しており、ホーム コントローラー フォルダーに配置するのが理にかなっています。2 番目のケースでは、コントローラーによって共有されるため、共有フォルダーに配置するのが理にかなっています。

どちらの場合でも、サブ フォルダーに配置することができます。Views/Home/Products と同様に、RendarPartial("Product/Single") を試してみて、何が起こるか見てみましょう。Home/Product/Single から Shared/Product/Single に解決しようとするかどうかはわかりません。サブフォルダーが機能する場合、Product と Article を論理的に分離できるように見えますが、それらはまだ Home コントローラーまたは Shared by all コントローラーのいずれかのメンバーであることを示しています。

]

Steve Sanderson によるこのブログ エントリをチェックしてください。

http://blog.codeville.net/2008/10/14/partial-requests-in-aspnet-mvc/

あなたがしていることは間違っていませんが、ビュー/コントローラーのフォルダー名の規則に反しているようです。とはいえ、コントローラーに依存しないビュー ユーザー コントロールを定義することは理にかなっていて、それらをネストすることは有効に思えます。だからわかんない!

とにかく、リンクはRenderPartialを使用して使用コントロールをレンダリングする代わりにメソッドを説明しているだけで、コントローラーアクションの戻り値(この場合はユーザーコントロール)をレンダリングするRenderPartialRequestのメソッドを定義しています。したがって、ユーザー コントロールを返すアクション リストを含む Product および Articles コントローラーを追加し、Home/Index ビューからこれら 2 つのアクションを呼び出すことができます。これは私にはより直感的に思えますが、単なる意見です。

彼は MVC Contrib のサブコントローラーについても言及しており、このようなものが ASP.NET MVC リリースの一部になることを望んでいることは確かです。

于 2008-11-11T18:14:23.587 に答える
2

MVCStoreFront サンプルを見ると、RenderPartial を呼び出すためにすべてが構造化されています。

Views
    Shared
        ProductSingle
        ProductList
        ArticleSingle
        ArticleList

次に、次の方法でレンダリングします。

<% Html.RenderPartial("ProductSingle", ViewData["ProductList"]); %>
<% Html.RenderPartial("ProductList", product); %>
<% Html.RenderPartial("ArticleSingle", article); %>
<% Html.RenderPartial("ArticleList", ViewData["ArticleList"]); %>
于 2008-11-11T20:56:34.240 に答える