2

別のディレクトリにある MVC ビューを動的にロードする VirtualPathProvider を作成しています。MVC (FileExists 内) の前に呼び出しを正常にインターセプトしましたが、VirtualPathProvider では、次のような未加工の事前にルーティングされた URL を取得します。

~/Apps/Administration/Account/LogOn

個人的に、私はMVCが探すことを知っています

~/Apps/Administration/Views/Account/LogOn.aspx

そして、ファイルの内容を読み取る必要があること

D:\SomeOtherNonWebRootDirectory\Apps\Administration\Views\Account\LogOn.aspx

しかし、「Views という名前のディレクトリを追加し、最後に aspx を追加する」というロジックをハードコーディングしたくありません。

このロジックはどこに保存され、仮想パス プロバイダーにどのように取得できますか?

ありがとう。はっきりしない場合は申し訳ありません。

4

3 に答える 3

4

編集済み

WebFormViewEngineプロパティを継承して設定するクラスを作成する必要がありViewLocationFormatsます (VirtualPathProviderViewEngine から継承)。

デフォルト値は、MVC ソース コードで確認できます。

public WebFormViewEngine() {
    MasterLocationFormats = new[] {
        "~/Views/{1}/{0}.master",
        "~/Views/Shared/{0}.master"
    };

    AreaMasterLocationFormats = new[] {
        "~/Areas/{2}/Views/{1}/{0}.master",
        "~/Areas/{2}/Views/Shared/{0}.master",
    };

    ViewLocationFormats = new[] {
        "~/Views/{1}/{0}.aspx",
        "~/Views/{1}/{0}.ascx",
        "~/Views/Shared/{0}.aspx",
        "~/Views/Shared/{0}.ascx"
    };

    AreaViewLocationFormats = new[] {
        "~/Areas/{2}/Views/{1}/{0}.aspx",
        "~/Areas/{2}/Views/{1}/{0}.ascx",
        "~/Areas/{2}/Views/Shared/{0}.aspx",
        "~/Areas/{2}/Views/Shared/{0}.ascx",
    };

    PartialViewLocationFormats = ViewLocationFormats;
    AreaPartialViewLocationFormats = AreaViewLocationFormats;
}

その後、コレクションをクリアしてViewEngines.Engines、ViewEngine インスタンスを追加する必要があります。

于 2010-08-18T17:46:26.787 に答える
0

答えは、MVC がコントローラーを適切に見つけられなかったというものでした。MVC が実際にコントローラーを適切に検出した場合、VirtualPathProvider によって処理される 2 つの要求があるはずです。

  1. 実際の URL が要求された最初の要求 (例: http://.../Account/LogOn )。

  2. 1. の要求の後にhttp://.../Views/Account/LogOn.aspxの FileExists チェックを行うと、FileExists の呼び出しで false が返されます。これにより、実際には aspx コンテンツが返されます。

于 2010-08-30T13:41:48.600 に答える
0

SLak が前述したように、カスタム ビュー エンジンを作成し、ビュー検索ロジックを FindView メソッドに追加する必要があります。

public class CustomViewEngine : VirtualPathProviderViewEngine

{

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)

    {
        //Set view path
        string viewPath = GetCurrentViewPath();

        //Set master path (if need be)
        string masterPath = GetCurrentMasterPath();

        return base.FindView(controllerContext, viewPath, masterPath, useCache);
    }

}

Application_Start では、View Engine を次のように登録できます。

 ViewEngines.Engines.Clear();
 ViewEngines.Engines.Add(new CustomViewEngine());
于 2010-08-18T23:00:16.640 に答える