2011-10-03 28 views
8

最近、IISのIProcessHostPreloadClientインターフェイスを使用してウォームアップのステップステップをWebアプリケーションに適用することができました(この設定方法についてはhereを参照してください)。アップ)。これは偉大な、または少なくとも私はそれが私がやった "巧妙な"ものの1つが私のコントローラを反復し、それらをレンダリングすることによって私のビューをプリロードしようとしていたからだと思った。IISウォームアップステップでASP.NET MVCビューをプリロードする

少しの試行錯誤の後、私はそれをうまく動作させて、すべてうまくいった。つまり、私のシステムに対するすべての検証がもはや機能しなくなったことに気付くまで、クライアントやサーバの検証は行われませんでした。 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 { } 
     } 
    } 
} 

答えて

3

問題は問題のコードではなく、実行される時刻にあります。コードをアクションに移すことで、ウォームアップのステップを問題なく実行できます。私の場合は、システムの設定後にウォームアップアクションを呼び出すためのインストールプロセスを取得するだけです。

3

ないあなたの質問への直接の答えは、私はあなたがデビッド・エボで

Precompiling MVC Razor views using RazorGeneratorを見てみる必要があり、これを行うための一つの理由は避けることだと思いますあなたのサイト が起動すると、実行時にコンパイルするものは何も残っていないので、実行時にヒットします。これは、多くのビューを持つサイトでは、 となる可能性があります。

+0

私はいくつかのグローバルRazorヘルパーメソッドを使用しています。それらを使用するためにRazorジェネレータを取得することはできません。それ以外の場合は、非常に便利なツールに見えます。 –

+1

私は、プリコンパイル・ビューが努力する価値があるとは確信していません。私は、重複するプロセスのリサイクルをサポートしている新しいIISアプリケーションの初期化が問題をより良く解決すると思います。 –

3

マイクロソフトの新しいモジュールが、以前のウォームアップモジュールに代わるIIS 8.0の一部です。このApplication Initialization Module for IIS 7.5は別途ダウンロードできます。

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

私は同様の質問に、詳細はHow to warm up an ASP.NET MVC application on IIS 7.5?で回答しました。

関連する問題