Beispiel #1
0
        /// <summary>
        /// Creates a new <see cref="CompiledViewDescriptor"/>. At least one of <paramref name="attribute"/> or
        /// <paramref name="item"/> must be non-<c>null</c>.
        /// </summary>
        /// <param name="item">The <see cref="RazorCompiledItem"/>.</param>
        /// <param name="attribute">The <see cref="RazorViewAttribute"/>.</param>
        public CompiledViewDescriptor(RazorCompiledItem item, RazorViewAttribute attribute)
        {
            if (item == null && attribute == null)
            {
                // We require at least one of these to be specified.
                throw new ArgumentException(Resources.FormatCompiledViewDescriptor_NoData(nameof(item), nameof(attribute)));
            }

            Item = item;

            //
            // For now we expect that MVC views and pages will still have either:
            // [RazorView(...)] or
            // [RazorPage(...)].
            //
            // In theory we could look at the 'Item.Kind' to determine what kind of thing we're dealing
            // with, but for compat reasons we're basing it on ViewAttribute since that's what 2.0 had.
            ViewAttribute = attribute;

            // We don't have access to the file provider here so we can't check if the files
            // even exist or what their checksums are. For now leave this empty, it will be updated
            // later.
            ExpirationTokens = Array.Empty <IChangeToken>();
            RelativePath     = ViewPath.NormalizePath(item?.Identifier ?? attribute.Path);
            IsPrecompiled    = true;
        }
Beispiel #2
0
        private CompilationResult GetCompilation(RazorProjectItem projectItem, RazorProjectFileSystem projectFileSystem)
        {
            using (IServiceScope scope = _serviceScopeFactory.CreateScope())
            {
                IServiceProvider serviceProvider = scope.ServiceProvider;

                // See RazorViewCompiler.CompileAndEmit()
                RazorProjectEngine  projectEngine  = serviceProvider.GetRequiredService <RazorProjectEngine>();
                RazorCodeDocument   codeDocument   = projectEngine.Process(projectItem);
                RazorCSharpDocument cSharpDocument = codeDocument.GetCSharpDocument();
                if (cSharpDocument.Diagnostics.Count > 0)
                {
                    throw (Exception)CreateCompilationFailedException.Invoke(
                              null,
                              new object[] { codeDocument, cSharpDocument.Diagnostics });
                }

                // Use the RazorViewCompiler to finish compiling the view for consistency with layouts
                IViewCompilerProvider viewCompilerProvider = serviceProvider.GetRequiredService <IViewCompilerProvider>();
                IViewCompiler         viewCompiler         = viewCompilerProvider.GetCompiler();
                Assembly assembly = (Assembly)CompileAndEmitMethod.Invoke(
                    viewCompiler,
                    new object[] { codeDocument, cSharpDocument.GeneratedCode });

                // Get the runtime item
                RazorCompiledItemLoader compiledItemLoader = new RazorCompiledItemLoader();
                RazorCompiledItem       compiledItem       = compiledItemLoader.LoadItems(assembly).SingleOrDefault();
                return(new CompilationResult(compiledItem));
            }
        }
        private static async Task <string> GetOutput <TModel>(Assembly assembly, RazorCompiledItem razorCompiledItem, TModel model)
        {
            using (var output = new StringWriter())
            {
                var compiledTemplate = assembly.GetType(razorCompiledItem.Type.FullName);
                var razorPage        = (RazorPage)Activator.CreateInstance(compiledTemplate);

                if (razorPage is RazorPage <TModel> page)
                {
                    AddViewData(page, model);
                }

                razorPage.ViewContext = new ViewContext
                {
                    Writer = output
                };

                razorPage.DiagnosticSource = new DiagnosticListener("GetOutput");
                razorPage.HtmlEncoder      = HtmlEncoder.Default;


                await razorPage.ExecuteAsync();

                return(output.ToString());
            }
        }
        private static async Task <string> GetRenderedOutput <TModel>(RazorCompiledItem razorCompiledItem, TModel model)
        {
            using var stringWriter = new StringWriter();
            var razorPage = GetRazorPageInstance(razorCompiledItem, model, stringWriter);
            await razorPage.ExecuteAsync();

            return(stringWriter.ToString());
        }
Beispiel #5
0
        private static CompiledViewDescriptor GetCompiledViewDescriptor(RazorCompiledItem item)
        {
            var itemAssembly       = item.Type.Assembly;
            var razorViewAttribute = itemAssembly.GetCustomAttributes <RazorViewAttribute>()
                                     .FirstOrDefault(attribute => attribute.ViewType == item.Type);

            return(new CompiledViewDescriptor(item, razorViewAttribute));
        }
Beispiel #6
0
    /// <summary>
    /// Gets the list of <see cref="IRazorSourceChecksumMetadata"/> associated with <paramref name="item"/>.
    /// </summary>
    /// <param name="item">The <see cref="RazorCompiledItem"/>.</param>
    /// <returns>A list of <see cref="IRazorSourceChecksumMetadata"/>.</returns>
    public static IReadOnlyList <IRazorSourceChecksumMetadata> GetChecksumMetadata(this RazorCompiledItem item)
    {
        if (item == null)
        {
            throw new ArgumentNullException(nameof(item));
        }

        return(item.Metadata.OfType <IRazorSourceChecksumMetadata>().ToArray());
    }
    /// <summary>
    /// Creates a new <see cref="CompiledViewDescriptor"/>.
    /// </summary>
    /// <param name="item">The <see cref="RazorCompiledItem"/>.</param>
    public CompiledViewDescriptor(RazorCompiledItem item)
    {
        if (item == null)
        {
            throw new ArgumentNullException(nameof(item));
        }

        Item         = item;
        RelativePath = ViewPath.NormalizePath(item.Identifier);
    }
        /// <summary>
        /// Creates a new <see cref="CompiledViewDescriptor"/>.
        /// </summary>
        /// <param name="item">The <see cref="RazorCompiledItem"/>.</param>
        public CompiledViewDescriptor(RazorCompiledItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            Item             = item;
            ExpirationTokens = Array.Empty <IChangeToken>();
            RelativePath     = ViewPath.NormalizePath(item.Identifier);
        }
        public WrappedRazorCompiledItem(RazorCompiledItem item)
        {
            _item = item;
            var assembly = _item.Type.Assembly.GetName().Name;

            if (assembly.EndsWith(".Views"))
            {
                assembly = assembly.Substring(0, assembly.Length - 6);
            }

            _identifier = $"/{assembly}{_item.Identifier}";
        }
Beispiel #10
0
        public static bool IsRecompilationSupported(RazorCompiledItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            // A Razor item only supports recompilation if its primary source file has a checksum.
            //
            // Other files (view imports) may or may not have existed at the time of compilation,
            // so we may not have checksums for them.
            var checksums = item.GetChecksumMetadata();

            return(checksums.Any(c => string.Equals(item.Identifier, c.Identifier, StringComparison.OrdinalIgnoreCase)));
        }
        private static RazorPage GetRazorPageInstance <TModel>(RazorCompiledItem razorCompiledItem, TModel model, TextWriter textWriter)
        {
            var razorPage = (RazorPage <TModel>)Activator.CreateInstance(razorCompiledItem.Type);

            razorPage.ViewData = new ViewDataDictionary <TModel>(
                new EmptyModelMetadataProvider(),
                new ModelStateDictionary())
            {
                Model = model
            };

            razorPage.ViewContext = new ViewContext
            {
                Writer = textWriter
            };

            razorPage.HtmlEncoder = HtmlEncoder.Default;
            return(razorPage);
        }
Beispiel #12
0
        public async Task RunAsync(Assembly assembly, HttpContext httpContext, string viewName, object model)
        {
            try
            {
                RazorCompiledItemLoader loader = new RazorCompiledItemLoader();
                RazorCompiledItem       item   = loader.LoadItems(assembly).SingleOrDefault();
                EmbeddedViewModel       view   = (EmbeddedViewModel)Activator.CreateInstance(item.Type);
                view.HttpContext = httpContext;
                view.ViewName    = viewName;
                view.Html        = new Html(httpContext);
                view.Url         = new Url();
                if (model != null)
                {
                    item.Type.GetProperty("Model").SetValue(view, model);
                }
                var result = await view.Execute();

                if (httpContext.Response.StatusCode == 200 && result is EmbededViewViewResult)
                {
                    await view.ExecuteAsync();
                }
                if (httpContext.Response.StatusCode == 200 && result is EmbededViewJsonResult)
                {
                    httpContext.Response.ContentType = "application/json";
                    await httpContext.Response.WriteAsync(((EmbededViewJsonResult)result).Json);
                }
                if (httpContext.Response.StatusCode == 200 && result is EmbededViewRedirectResult)
                {
                    httpContext.Response.Redirect(((EmbededViewRedirectResult)result).Url);
                }
            }
            finally
            {
                BufferedStream bufferedStream = httpContext.Response.Body as BufferedStream;
                if (bufferedStream != null)
                {
                    await bufferedStream.FlushAsync();
                }
            }
        }
Beispiel #13
0
 public HotReloadRazorCompiledItem(RazorCompiledItem previous, Type type)
 {
     _previous = previous;
     Type      = type;
 }
Beispiel #14
0
 public CompilationResult(RazorCompiledItem item)
 {
     CompiledItem = item;
 }
Beispiel #15
0
        // Validates that we can use an existing precompiled view by comparing checksums with files on
        // disk.
        public static bool IsItemValid(RazorProjectFileSystem fileSystem, RazorCompiledItem item)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException(nameof(fileSystem));
            }

            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            var checksums = item.GetChecksumMetadata();

            // The checksum that matches 'Item.Identity' in this list is significant. That represents the main file.
            //
            // We don't really care about the validation unless the main file exists. This is because we expect
            // most sites to have some _ViewImports in common location. That means that in the case you're
            // using views from a 3rd party library, you'll always have **some** conflicts.
            //
            // The presence of the main file with the same content is a very strong signal that you're in a
            // development scenario.
            var primaryChecksum = checksums
                                  .FirstOrDefault(c => string.Equals(item.Identifier, c.Identifier, StringComparison.OrdinalIgnoreCase));

            if (primaryChecksum == null)
            {
                // No primary checksum, assume valid.
                return(true);
            }

            var projectItem = fileSystem.GetItem(primaryChecksum.Identifier, fileKind: null);

            if (!projectItem.Exists)
            {
                // Main file doesn't exist - assume valid.
                return(true);
            }

            var sourceDocument = RazorSourceDocument.ReadFrom(projectItem);

            if (!string.Equals(sourceDocument.GetChecksumAlgorithm(), primaryChecksum.ChecksumAlgorithm, StringComparison.OrdinalIgnoreCase) ||
                !ChecksumsEqual(primaryChecksum.Checksum, sourceDocument.GetChecksum()))
            {
                // Main file exists, but checksums not equal.
                return(false);
            }

            for (var i = 0; i < checksums.Count; i++)
            {
                var checksum = checksums[i];
                if (string.Equals(item.Identifier, checksum.Identifier, StringComparison.OrdinalIgnoreCase))
                {
                    // Ignore primary checksum on this pass.
                    continue;
                }

                var importItem = fileSystem.GetItem(checksum.Identifier, fileKind: null);
                if (!importItem.Exists)
                {
                    // Import file doesn't exist - assume invalid.
                    return(false);
                }

                sourceDocument = RazorSourceDocument.ReadFrom(importItem);
                if (!string.Equals(sourceDocument.GetChecksumAlgorithm(), checksum.ChecksumAlgorithm) ||
                    !ChecksumsEqual(checksum.Checksum, sourceDocument.GetChecksum()))
                {
                    // Import file exists, but checksums not equal.
                    return(false);
                }
            }

            return(true);
        }