2013-05-02 8 views
5

私はHtmlHelperという拡張子を書いています。テンプレートの存在を名前で検索する必要があります。問題のテンプレートは、コンテキストに応じて表示テンプレートまたはエディタテンプレートであってもよい。私の最初の考えはViewEngines.Engines.FindPartialViewメソッドを使用することでした。ただし、この方法では~/Views/Shared/DisplayTemplates~/Views/Shared/EditorTemplatesというディレクトリは検索されていないようです。
これは正当な理由があると思います。結局のところ、ViewEngineは、コンテキストの追加情報なしでディスプレイまたはエディタテンプレートを返すかどうかをどのように知っていますか?名前でMVCテンプレートビューを検索

だから、質問につながること:どのように私は、特定のを検索することができEditorTemplate/DisplayTemplate私はこれらの場所を含めるようにViewEnginesコレクションにカスタムビューエンジンを追加すると考えられてきました。しかし、これは問題になるかもしれないと心配しています。

私の主な関心事は、DisplayTemplate/EditorTemplateビューが意図しない何かをアップしましかもしれないということです。他の誰かがこれを問題と見なしていますか?
DisplayTemplateViewEngine/EditorTemplateViewEngineインスタンスを必要に応じて新しくし、ViewEnginesコレクションにこの特定の機能がないようにしておくことをお勧めしますか?
他にも何かがありますか?

答えて

4

をチェックソース! TemplateHelpersクラス(MVCランタイムの内部)から、テンプレートのレンダリング時にDataBoundControlModeが考慮されることを確認できました。答えは簡単でした!私がしなければならないのは、テンプレート名の先頭に適切なテンプレートディレクターを付けることだけです。したがって、ディスプレイテンプレートを見つけるには:

var metadata = ModelMetadata.FromLambdaExpression(expression, HtmlHelper.ViewData); 
ViewEngines.Engines.FindPartialView(
    _controllerContext, 
    string.Format("DisplayTemplates/{0}", metadata.TemplateHint)) 

追加のビューエンジンやルーティングは必要ありません。アプリケーションに興味がある場合は、ヘルパーが特定のモデルのUIコンポーネントを自動生成しています。自動化されたレンダリングをバイパスするカスタムテンプレートの存在を有効にしたかったのです。

+0

これが答えです。しかし、私は数日の間それをそのようにマークすることはできません。申し訳ありませんが、あなたがこの投稿に魅了されたのは、明らかに「未回答」の状態だからです。 –

+0

metadata.TemplateHintとは何か、それはどこから来たのですか? – xr280xr

+1

@ xr280xr:メタデータ定義を含むように更新されました。あなたに仕えることを願っています! –

0

WebFormViewEngineには、ビューを検索する場所(パターン)を定義するプロパティがいくつかあります。

使用するビューエンジンの規則に従うか、カスタムビューパスを使用してカスタムビューエンジン(Razorを拡張するためのカスタムビューエンジン)を作成します。

後者はhereを説明します

public class CustomViewEngine : RazorViewEngine 
{ 
    public CustomViewEngine() 
    { 
     var viewLocations = new[] { 
      "~/Views/{1}/{0}.cshtml", 
      "~/Views/Shared/{0}.cshtml", 
      "~/Views/Shared/DisplayTemplates/{0}.cshtml", 
      "~/Views/Shared/DisplayTemplates/{1}/{0}.cshtml", 
      // etc 
     }; 

     this.PartialViewLocationFormats = viewLocations; 
     this.ViewLocationFormats = viewLocations; 
    } 
} 

だから私はあなたのヘルパーにあなたが現在のビューエンジンを検索し、そのビューのロケーションパスを検索し、それらを順番に検索する必要がありますね。 HTMLヘルパーは、現在実行中のビューを取得するためのメソッドまたはプロパティを持っていませんか?

+0

返信いただきありがとうございます。私は実際に慣例を破るわけではない。私の構造は、期待されるMVCアーキテクチャの定義に従っています。問題は、ViewEnginesCollectionのFindPartialViewメソッドは、表示またはエディタのバージョンを希望するかどうかわからないため、これらの場所を検索しないことです。しかし、私は解決策を見つけました。参考まで私の答えを見てください。再度、感謝します。 –

+0

1)あなたの例のコードは、デフォルトのかみそりの動作ですか? 2) '{0}'と '{1} 'は何を指していますか? – Shimmy

+0

@Shimmy [これがデフォルトです](https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/RazorViewEngine.cs)。置き換えられた値は '{0}' =ビュー名、 '{1}' =コントローラ名、{2} '=エリア名です(このファイルの下部にある' 'ViewLocation''と' 'AreaAwareViewLocation'(https: //github.com/ASP-NET-MVC/aspnetwebstack/blob/4e40cdef9c8a8226685f95ef03b746bc8322aa92/src/System.Web.Mvc/VirtualPathProviderViewEngine.cs))。 – CodeCaster

0

なぜあなたはちょうど私が絶対にMVCフレームワークが開いていることを愛する

string path = Server.MapPath("~/View/"); 

相対パスをマッピングして、ファイルの終了ベース場合は、その特定のディレクトリに.cshtmlの出口の上

string fileName = "MyView.cshtml"; 
if (File.Exists(path + fileName)) 
    //do somethings 
else 
    //do another things 
+0

ViewEngineを使用するメリットの1つは、テスト可能にすることができます。このソリューションは単体テストにとって本当に難しいものです。しかし、あなたの入力にはうれしい! –