8

IProcessHostPreloadClient私は最近、インターフェイスを使用してウォームアップ ステップを Web アプリケーションに適用する IIS の機能をいじり始めました(設定方法のガイダンスについては、こちらを参照してください)。私が行った「賢い」ことの 1 つは、コントローラーを繰り返し処理してレンダリングすることにより、ビューをプリロードしようとすることだったからです。

少し試行錯誤した後、動作するようになり、すべてがうまくいきました。つまり、システムのすべての検証が機能しなくなったことに気付くまで、クライアントとサーバーの検証も機能しませんでした。MVC が初めてビューを取得したときに、通常は検証がビューに接続されていると思いますが、そうできませんでした。これを私のソリューションに含める方法や、別の方法で行う方法を知っている人はいますか?

コード:

public class Warmup : IProcessHostPreloadClient
{
    public void Preload(string[] parameters)
    {
        //Pre-render all views
        AutoPrimeViewCache("QASW.Web.Mvc.Controllers", @"Views\");
        AutoPrimeViewCache("QASW.Web.Mvc.Areas.Api.Controllers", @"Areas\Api\Views\", "Api");
    }

    private void AutoPrimeViewCache(string controllerNamespace, string relativeViewPath, string area = null)
    {
        var controllerTypes = typeof(Warmup).Assembly.GetTypes().Where(t => t.Namespace == controllerNamespace && (t == typeof(Controller) || t.IsSubclassOf(typeof(Controller))));
        var controllers = controllerTypes.Select(t => new { Instance = (Controller)Activator.CreateInstance(t), Name = t.Name.Remove("Controller") });

        foreach (var controller in controllers)
        {
            var viewPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, relativeViewPath + controller.Name);
            var viewDir = new DirectoryInfo(viewPath);
            if (viewDir.Exists)
            {
                var viewNames = viewDir.EnumerateFiles("*.cshtml").Select(f => f.Name.Remove(".cshtml")).ToArray();
                PreloadController(controller.Instance, area, viewNames);
            }
        }
    }

    private void PreloadController(Controller controller, string area, params string[] views)
    {
        var viewEngine = new RazorViewEngine();

        var controllerName = controller.GetType().Name.Remove("Controller");
        var http = new HttpContextWrapper(new HttpContext(new HttpRequest(null, "http://a.b.com", null), new HttpResponse(TextWriter.Null)));
        var routeDescription = area == null ? "{controller}/{action}/{id}" : area + "/{controller}/{action}/{id}";
        var route = new RouteCollection().MapRoute(
            "Default", // Route name
            routeDescription, // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

        var routeData = new RouteData(route, route.RouteHandler);
        routeData.Values.Add("controller", controllerName);
        if (area != null)
        {
            routeData.Values.Add("area", area);
            routeData.DataTokens.Add("area", area);
        }
        routeData.DataTokens.Add("controller", controllerName);
        routeData.Values.Add("id", 1);
        routeData.DataTokens.Add("id", 1);
        var controllerContext = new ControllerContext(http, routeData, controller);
        var vDic = new ViewDataDictionary();
        var vTemp = new TempDataDictionary();

        foreach (var view in views)
        {
            var viewResult = viewEngine.FindView(controllerContext, view, null, false);
            if (viewResult.View == null)
                throw new ArgumentException("View not found: {0} (Controller: {1})".Args(view, controllerName));
            var viewContext = new ViewContext(controllerContext, viewResult.View, vDic, vTemp, TextWriter.Null);
            try { viewResult.View.Render(viewContext, TextWriter.Null); }
            catch { }
        }
    }
}
4

3 に答える 3

3

以前のウォームアップ モジュールに取って代わる IIS 8.0 の一部である Microsoft の新しいモジュールがあります。このIIS 7.5 用のアプリケーション初期化モジュールは、個別にダウンロードできます。

モジュールは、サーバーが要求の受け入れを開始する前に完了しなければならない要求の数を指定できるウォームアップ フェーズを作成します。これらのリクエストは、達成しようとしているものよりも堅牢な方法ですべてのビューを実行およびコンパイルします。

IIS 7.5 で ASP.NET MVC アプリケーションをウォームアップする方法で、同様の質問に詳細を記載して回答しました。.

于 2012-10-03T19:27:07.567 に答える
3

あなたの質問への直接の回答ではありませんが、David EbboによるRazorGeneratorを使用したMVC Razorビューのプリコンパイルをご覧になる必要があると思います

これを行う理由の 1 つは、実行時にコンパイルするものが何も残っていないため、サイトの開始時にランタイム ヒットを回避することです。これは、多くのビューを持つサイトで重要になる可能性があります。

于 2011-10-03T12:11:14.273 に答える
3

問題は問題のコードではなく、それが実行される時間です。コードをアクションに移動すると、問題なくウォームアップ ステップを実行できます。私の場合、システムが構成された後、インストール プロセスでウォームアップ アクションを呼び出すだけだと思います。

于 2011-11-09T09:25:39.323 に答える