예제 #1
0
        public string RenderToStringAsync(string viewName, object model)
        {
            var httpContext = new DefaultHttpContext {
                RequestServices = _serviceProvider
            };
            var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

            using (var sw = new StringWriter())
            {
                var viewResult = _razorViewEngine.FindView(actionContext, viewName, false);

                if (viewResult.View == null)
                {
                    throw new ArgumentNullException($"{viewName} does not match any available view");
                }

                var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
                {
                    Model = model
                };

                var viewContext = new ViewContext(
                    actionContext,
                    viewResult.View,
                    viewDictionary,
                    new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
                    sw,
                    new HtmlHelperOptions()
                    );

                viewResult.View.RenderAsync(viewContext);
                return(sw.ToString());
            }
        }
예제 #2
0
        public IEnumerable <IDocument> Execute(IReadOnlyList <IDocument> inputs, IExecutionContext context)
        {
            // Register all the MVC and Razor services
            // In the future, if DI is implemented for all Wyam, the IExecutionContext would be registered as a service
            // and the IHostingEnviornment would be registered as transient with the execution context provided in ctor
            IServiceCollection serviceCollection = new ServiceCollection();
            IMvcCoreBuilder    builder           = serviceCollection
                                                   .AddMvcCore()
                                                   .AddRazorViewEngine();

            builder.PartManager.FeatureProviders.Add(new MetadataReferenceFeatureProvider(context));
            serviceCollection.Configure <RazorViewEngineOptions>(options =>
            {
                options.ViewLocationExpanders.Add(new ViewLocationExpander());
            });
            serviceCollection
            .AddSingleton <ILoggerFactory, TraceLoggerFactory>()
            .AddSingleton <DiagnosticSource, SilentDiagnosticSource>()
            .AddSingleton <IHostingEnvironment, HostingEnvironment>()
            .AddSingleton <ObjectPoolProvider, DefaultObjectPoolProvider>()
            .AddSingleton <IExecutionContext>(context)
            .AddSingleton <IBasePageTypeProvider>(new BasePageTypeProvider(_basePageType ?? typeof(RazorPage)))
            .AddScoped <IMvcRazorHost, RazorHost>();
            IServiceProvider services = serviceCollection.BuildServiceProvider();

            // Eliminate input documents that we shouldn't process
            List <IDocument> validInputs = inputs
                                           .Where(x => _ignorePrefix == null ||
                                                  !x.ContainsKey(Keys.SourceFileName) ||
                                                  !x.FilePath(Keys.SourceFileName).FullPath.StartsWith(_ignorePrefix))
                                           .ToList();

            // Compile and evaluate the pages in parallel
            IServiceScopeFactory scopeFactory = services.GetRequiredService <IServiceScopeFactory>();

            return(validInputs.AsParallel().Select(input =>
            {
                Trace.Verbose("Compiling Razor for {0}", input.SourceString());
                using (var scope = scopeFactory.CreateScope())
                {
                    // Get services
                    IRazorViewEngine viewEngine = services.GetRequiredService <IRazorViewEngine>();
                    IRazorPageActivator pageActivator = services.GetRequiredService <IRazorPageActivator>();
                    HtmlEncoder htmlEncoder = services.GetRequiredService <HtmlEncoder>();
                    IRazorPageFactoryProvider pageFactoryProvider = services.GetRequiredService <IRazorPageFactoryProvider>();
                    IRazorCompilationService razorCompilationService = services.GetRequiredService <IRazorCompilationService>();
                    IHostingEnvironment hostingEnviornment = services.GetRequiredService <IHostingEnvironment>();

                    // Compile the view
                    string relativePath = GetRelativePath(input, context);
                    FilePath viewStartLocationPath = _viewStartPath?.Invoke <FilePath>(input, context);
                    string viewStartLocation = viewStartLocationPath != null ? GetRelativePath(viewStartLocationPath, context) : null;
                    string layoutLocation = _layoutPath?.Invoke <FilePath>(input, context)?.FullPath;
                    IView view;
                    using (Stream stream = input.GetStream())
                    {
                        view = GetViewFromStream(relativePath, stream, viewStartLocation, layoutLocation, viewEngine, pageActivator,
                                                 htmlEncoder, pageFactoryProvider, hostingEnviornment.WebRootFileProvider, razorCompilationService);
                    }

                    // Render the view
                    Trace.Verbose("Processing Razor for {0}", input.SourceString());
                    using (StringWriter output = new StringWriter())
                    {
                        Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext =
                            GetViewContext(scope.ServiceProvider, view, input, context, output);
                        viewContext.View.RenderAsync(viewContext).GetAwaiter().GetResult();
                        return context.GetDocument(input, output.ToString());
                    }
                }
            }));
        }