예제 #1
0
        // Token: 0x0600017E RID: 382 RVA: 0x00006EDC File Offset: 0x000050DC
        private Task <CompiledViewDescriptor> OnCacheMiss(string normalizedPath)
        {
            object cacheLock = this._cacheLock;
            ViewCompilerWorkItem    viewCompilerWorkItem;
            MemoryCacheEntryOptions memoryCacheEntryOptions;
            TaskCompletionSource <CompiledViewDescriptor> taskCompletionSource;

            lock (cacheLock)
            {
                Task <CompiledViewDescriptor> result;
                if (CacheExtensions.TryGetValue <Task <CompiledViewDescriptor> >(this._cache, normalizedPath, out result))
                {
                    return(result);
                }
                CompiledViewDescriptor precompiledView;
                if (this._precompiledViews.TryGetValue(normalizedPath, out precompiledView))
                {
                    this._logger.ViewCompilerLocatedCompiledViewForPath(normalizedPath);
                    viewCompilerWorkItem = this.CreatePrecompiledWorkItem(normalizedPath, precompiledView);
                }
                else
                {
                    viewCompilerWorkItem = this.CreateRuntimeCompilationWorkItem(normalizedPath);
                }
                memoryCacheEntryOptions = new MemoryCacheEntryOptions();
                for (int i = 0; i < viewCompilerWorkItem.ExpirationTokens.Count; i++)
                {
                    memoryCacheEntryOptions.ExpirationTokens.Add(viewCompilerWorkItem.ExpirationTokens[i]);
                }
                taskCompletionSource = new TaskCompletionSource <CompiledViewDescriptor>();
                if (!viewCompilerWorkItem.SupportsCompilation)
                {
                    taskCompletionSource.SetResult(viewCompilerWorkItem.Descriptor);
                }
                _cacheKeyList.Add(normalizedPath);
                CacheExtensions.Set <Task <CompiledViewDescriptor> >(this._cache, normalizedPath, taskCompletionSource.Task, memoryCacheEntryOptions);
            }
            if (viewCompilerWorkItem.SupportsCompilation)
            {
                CompiledViewDescriptor descriptor = viewCompilerWorkItem.Descriptor;
                if (((descriptor != null) ? descriptor.Item : null) != null && ChecksumValidator.IsItemValid(this._projectEngine.FileSystem, viewCompilerWorkItem.Descriptor.Item))
                {
                    taskCompletionSource.SetResult(viewCompilerWorkItem.Descriptor);
                    return(taskCompletionSource.Task);
                }
                this._logger.ViewCompilerInvalidingCompiledFile(viewCompilerWorkItem.NormalizedPath);
                try
                {
                    CompiledViewDescriptor compiledViewDescriptor = this.CompileAndEmit(normalizedPath);
                    compiledViewDescriptor.ExpirationTokens = memoryCacheEntryOptions.ExpirationTokens;
                    taskCompletionSource.SetResult(compiledViewDescriptor);
                }
                catch (Exception exception)
                {
                    taskCompletionSource.SetException(exception);
                }
            }
            return(taskCompletionSource.Task);
        }
예제 #2
0
    public void IsItemValid_NoChecksumAttributes_ReturnsTrue()
    {
        // Arrange
        var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[] { });

        // Act
        var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);

        // Assert
        Assert.True(result);
    }
예제 #3
0
    public void IsItemValid_NoPrimaryChecksumAttribute_ReturnsTrue()
    {
        // Arrange
        var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[]
        {
            new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"),
            new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/About.cstml"),
        });

        // Act
        var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);

        // Assert
        Assert.True(result);
    }
예제 #4
0
    public void IsItemValid_PrimaryFileDoesNotExist_ReturnsTrue()
    {
        // Arrange
        var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[]
        {
            new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"),
            new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"),
        });

        ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/_ViewImports.cstml", "dkdkfkdf")); // This will be ignored

        // Act
        var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);

        // Assert
        Assert.True(result);
    }
        private void CreateModels(PageRouteModelProviderContext context)
        {
            var rootDirectory = _pagesOptions.RootDirectory;

            if (!rootDirectory.EndsWith("/", StringComparison.Ordinal))
            {
                rootDirectory = rootDirectory + "/";
            }

            var areaRootDirectory = _pagesOptions.AreaRootDirectory;

            if (!areaRootDirectory.EndsWith("/", StringComparison.Ordinal))
            {
                areaRootDirectory = areaRootDirectory + "/";
            }

            foreach (var viewDescriptor in GetViewDescriptors(_applicationManager))
            {
                if (viewDescriptor.Item != null && !ChecksumValidator.IsItemValid(_razorProjectEngine.FileSystem, viewDescriptor.Item))
                {
                    // If we get here, this compiled Page has different local content, so ignore it.
                    continue;
                }

                var            relativePath  = viewDescriptor.RelativePath;
                var            routeTemplate = GetRouteTemplate(viewDescriptor);
                PageRouteModel routeModel    = null;

                // When RootDirectory and AreaRootDirectory overlap (e.g. RootDirectory = '/', AreaRootDirectory = '/Areas'), we
                // only want to allow a page to be associated with the area route.
                if (_pagesOptions.AllowAreas && relativePath.StartsWith(areaRootDirectory, StringComparison.OrdinalIgnoreCase))
                {
                    routeModel = _routeModelFactory.CreateAreaRouteModel(relativePath, routeTemplate);
                }
                else if (relativePath.StartsWith(rootDirectory, StringComparison.OrdinalIgnoreCase))
                {
                    routeModel = _routeModelFactory.CreateRouteModel(relativePath, routeTemplate);
                }

                if (routeModel != null)
                {
                    context.RouteModels.Add(routeModel);
                }
            }
        }
예제 #6
0
    public void IsItemValid_ImportFileExistsButDoesNotMatch_ReturnsFalse()
    {
        // Arrange
        var item = new TestRazorCompiledItem(typeof(string), "mvc.1.0.view", "/Views/Home/Index.cstml", new object[]
        {
            new RazorSourceChecksumAttribute("SHA1", GetChecksum("some import"), "/Views/Home/_ViewImports.cstml"),
            new RazorSourceChecksumAttribute("SHA1", GetChecksum("some content"), "/Views/Home/Index.cstml"),
        });

        ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/Index.cstml", "some content"));
        ProjectFileSystem.Add(new TestRazorProjectItem("/Views/Home/_ViewImports.cstml", "some other import"));

        // Act
        var result = ChecksumValidator.IsItemValid(ProjectFileSystem, item);

        // Assert
        Assert.False(result);
    }
        private void CreateModels(IList <PageRouteModel> results)
        {
            var rootDirectory = _pagesOptions.RootDirectory;

            if (!rootDirectory.EndsWith("/", StringComparison.Ordinal))
            {
                rootDirectory = rootDirectory + "/";
            }

            var areaRootDirectory = _pagesOptions.AreaRootDirectory;

            if (!areaRootDirectory.EndsWith("/", StringComparison.Ordinal))
            {
                areaRootDirectory = areaRootDirectory + "/";
            }

            foreach (var viewDescriptor in GetViewDescriptors(_applicationManager))
            {
                if (viewDescriptor.Item != null && !ChecksumValidator.IsItemValid(_templateEngine.Project, viewDescriptor.Item))
                {
                    // If we get here, this compiled Page has different local content, so ignore it.
                    continue;
                }

                PageRouteModel model = null;
                // When RootDirectory and AreaRootDirectory overlap (e.g. RootDirectory = '/', AreaRootDirectory = '/Areas'), we
                // only want to allow a page to be associated with the area route.
                if (_pagesOptions.AllowAreas && viewDescriptor.RelativePath.StartsWith(areaRootDirectory, StringComparison.OrdinalIgnoreCase))
                {
                    model = GetAreaPageRouteModel(areaRootDirectory, viewDescriptor);
                }
                else if (viewDescriptor.RelativePath.StartsWith(rootDirectory, StringComparison.OrdinalIgnoreCase))
                {
                    model = GetPageRouteModel(rootDirectory, viewDescriptor);
                }

                if (model != null)
                {
                    results.Add(model);
                }
            }
        }
예제 #8
0
    private Task <CompiledViewDescriptor> OnCacheMiss(string normalizedPath)
    {
        ViewCompilerWorkItem item;
        TaskCompletionSource <CompiledViewDescriptor> taskSource;
        MemoryCacheEntryOptions cacheEntryOptions;

        // Safe races cannot be allowed when compiling Razor pages. To ensure only one compilation request succeeds
        // per file, we'll lock the creation of a cache entry. Creating the cache entry should be very quick. The
        // actual work for compiling files happens outside the critical section.
        lock (_cacheLock)
        {
            // Double-checked locking to handle a possible race.
            if (_cache.TryGetValue(normalizedPath, out Task <CompiledViewDescriptor> result))
            {
                return(result);
            }

            if (_precompiledViews.TryGetValue(normalizedPath, out var precompiledView))
            {
                Log.ViewCompilerLocatedCompiledViewForPath(_logger, normalizedPath);
                item = CreatePrecompiledWorkItem(normalizedPath, precompiledView);
            }
            else
            {
                item = CreateRuntimeCompilationWorkItem(normalizedPath);
            }

            // At this point, we've decided what to do - but we should create the cache entry and
            // release the lock first.
            cacheEntryOptions = new MemoryCacheEntryOptions();

            Debug.Assert(item.ExpirationTokens != null);
            for (var i = 0; i < item.ExpirationTokens.Count; i++)
            {
                cacheEntryOptions.ExpirationTokens.Add(item.ExpirationTokens[i]);
            }

            taskSource = new TaskCompletionSource <CompiledViewDescriptor>(creationOptions: TaskCreationOptions.RunContinuationsAsynchronously);
            if (item.SupportsCompilation)
            {
                // We'll compile in just a sec, be patient.
            }
            else
            {
                // If we can't compile, we should have already created the descriptor
                Debug.Assert(item.Descriptor != null);
                taskSource.SetResult(item.Descriptor);
            }

            _cache.Set(normalizedPath, taskSource.Task, cacheEntryOptions);
        }

        // Now the lock has been released so we can do more expensive processing.
        if (item.SupportsCompilation)
        {
            Debug.Assert(taskSource != null);

            if (item.Descriptor?.Item != null &&
                ChecksumValidator.IsItemValid(_projectEngine.FileSystem, item.Descriptor.Item))
            {
                // If the item has checksums to validate, we should also have a precompiled view.
                Debug.Assert(item.Descriptor != null);

                taskSource.SetResult(item.Descriptor);
                return(taskSource.Task);
            }

            Log.ViewCompilerInvalidatingCompiledFile(_logger, item.NormalizedPath);
            try
            {
                var descriptor = CompileAndEmit(normalizedPath);
                descriptor.ExpirationTokens = cacheEntryOptions.ExpirationTokens;
                taskSource.SetResult(descriptor);
            }
            catch (Exception ex)
            {
                taskSource.SetException(ex);
            }
        }

        return(taskSource.Task);
    }
예제 #9
0
        private Task <CompiledViewDescriptor> OnCacheMiss(string normalizedPath)
        {
            ViewCompilerWorkItem item;
            TaskCompletionSource <CompiledViewDescriptor> taskSource;
            MemoryCacheEntryOptions cacheEntryOptions;

            lock (_cacheLock)
            {
                if (_cache.TryGetValue(normalizedPath, out Task <CompiledViewDescriptor> result))
                {
                    return(result);
                }

                if (_precompiledViews.TryGetValue(normalizedPath, out var precompiledView))
                {
                    _logger.ViewCompilerLocatedCompiledViewForPath(normalizedPath);
                    item = CreatePrecompiledWorkItem(normalizedPath, precompiledView);
                }
                else
                {
                    item = CreateRuntimeCompilationWorkItem(normalizedPath);
                }

                cacheEntryOptions = new MemoryCacheEntryOptions();

                Debug.Assert(item.ExpirationTokens != null);
                for (var i = 0; i < item.ExpirationTokens.Count; i++)
                {
                    cacheEntryOptions.ExpirationTokens.Add(item.ExpirationTokens[i]);
                }

                taskSource = new TaskCompletionSource <CompiledViewDescriptor>();
                if (item.SupportsCompilation)
                {
                }
                else
                {
                    Debug.Assert(item.Descriptor != null);
                    taskSource.SetResult(item.Descriptor);
                }

                _cache.Set(normalizedPath, taskSource.Task, cacheEntryOptions);
            }

            if (item.SupportsCompilation)
            {
                Debug.Assert(taskSource != null);

                if (item.Descriptor?.Item != null &&
                    ChecksumValidator.IsItemValid(_projectEngine.FileSystem, item.Descriptor.Item))
                {
                    Debug.Assert(item.Descriptor != null);

                    taskSource.SetResult(item.Descriptor);
                    return(taskSource.Task);
                }

                _logger.ViewCompilerInvalidingCompiledFile(item.NormalizedPath);
                try
                {
                    var descriptor = CompileAndEmit(normalizedPath);
                    descriptor.ExpirationTokens = cacheEntryOptions.ExpirationTokens;
                    taskSource.SetResult(descriptor);
                }
                catch (Exception ex)
                {
                    taskSource.SetException(ex);
                }
            }

            return(taskSource.Task);
        }