Preload ASP.NET MVC Views during IIS Warm Up

I recently started playing with the ability of IIS to apply the warm-up step step to my web application using the IProcessHostPreloadClient interface (see here for information on how to install this). It worked out great, or at least I thought it happened because one of the smart things I did was try to preload my views, iterate over my controllers and render them.

After some trial and error, I got it to work, and everything was fine. That is, until I noticed that all the checks for my system no longer work, neither the client check, nor the server. I assume that validation usually connects to the views when MVC first gets the view, and I could not do it. Does anyone have an idea how this could be included in my solution or perhaps done differently?

The code:

 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://abcom", 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 { } } } } 
+8
c # asp.net-mvc
source share
3 answers

The problem is not the code in the question, but what time it runs. Moving the code into action allows me to complete the warm-up step without problems. In my case, I think I’ll just ask the installation process to trigger a warm-up action after the system has been configured.

+3
source share

An immediate answer to your question, but I think you should take a look at Precompiling MVC Razor Views using RazorGenerator by David Ebbo

One reason for this is to avoid any harm at runtime when your site starts up, since there is nothing to compile at runtime. This can be significant on sites with many kinds.

+3
source share

There is a new module from Microsoft, which is part of IIS 8.0, which overrides the previous warm-up module. This application initialization module for IIS 7.5 is available as a separate download.

The module will create a warm-up phase where you can specify the number of requests that must be completed before the server starts accepting requests. These queries will execute and compile all your representations in a more robust way than what you are trying to achieve.

I answered a similar question with more details in How to heat up an ASP.NET MVC application on IIS 7.5? .

+3
source share

All Articles