Add support for PageStarts
This commit is contained in:
parent
c95c2a5a6d
commit
8d5abd433f
|
|
@ -19,6 +19,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
_provider = provider;
|
_provider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override RazorProjectItem GetItem(string path)
|
||||||
|
{
|
||||||
|
EnsureValidPath(path);
|
||||||
|
var fileInfo = _provider.GetFileInfo(path);
|
||||||
|
return new DefaultRazorProjectItem(fileInfo, basePath: string.Empty, path: path);
|
||||||
|
}
|
||||||
|
|
||||||
public override IEnumerable<RazorProjectItem> EnumerateItems(string path)
|
public override IEnumerable<RazorProjectItem> EnumerateItems(string path)
|
||||||
{
|
{
|
||||||
if (path == null)
|
if (path == null)
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
|
|
||||||
public override string Path { get; }
|
public override string Path { get; }
|
||||||
|
|
||||||
|
public override bool Exists => _fileInfo.Exists;
|
||||||
|
|
||||||
public override string PhysicalPath => _fileInfo.PhysicalPath;
|
public override string PhysicalPath => _fileInfo.PhysicalPath;
|
||||||
|
|
||||||
public override Stream Read()
|
public override Stream Read()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a Razor Page.
|
||||||
|
/// </summary>
|
||||||
|
public class PageResultExecutor : ViewExecutor
|
||||||
|
{
|
||||||
|
private readonly IRazorViewEngine _razorViewEngine;
|
||||||
|
private readonly IRazorPageActivator _razorPageActivator;
|
||||||
|
private readonly HtmlEncoder _htmlEncoder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="PageResultExecutor"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="writerFactory">The <see cref="IHttpResponseStreamWriterFactory"/>.</param>
|
||||||
|
/// <param name="compositeViewEngine">The <see cref="ICompositeViewEngine"/>.</param>
|
||||||
|
/// <param name="razorViewEngine">The <see cref="IRazorViewEngine"/>.</param>
|
||||||
|
/// <param name="razorPageActivator">The <see cref="IRazorPageActivator"/>.</param>
|
||||||
|
/// <param name="diagnosticSource">The <see cref="DiagnosticSource"/>.</param>
|
||||||
|
/// <param name="htmlEncoder">The <see cref="HtmlEncoder"/>.</param>
|
||||||
|
public PageResultExecutor(
|
||||||
|
IHttpResponseStreamWriterFactory writerFactory,
|
||||||
|
ICompositeViewEngine compositeViewEngine,
|
||||||
|
IRazorViewEngine razorViewEngine,
|
||||||
|
IRazorPageActivator razorPageActivator,
|
||||||
|
DiagnosticSource diagnosticSource,
|
||||||
|
HtmlEncoder htmlEncoder)
|
||||||
|
: base(writerFactory, compositeViewEngine, diagnosticSource)
|
||||||
|
{
|
||||||
|
_razorViewEngine = razorViewEngine;
|
||||||
|
_razorPageActivator = razorPageActivator;
|
||||||
|
_htmlEncoder = htmlEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a Razor Page asynchronously.
|
||||||
|
/// </summary>
|
||||||
|
public virtual Task ExecuteAsync(PageContext pageContext, PageViewResult result)
|
||||||
|
{
|
||||||
|
if (result.Model != null)
|
||||||
|
{
|
||||||
|
pageContext.ViewData.Model = result.Model;
|
||||||
|
}
|
||||||
|
|
||||||
|
var view = new RazorView(_razorViewEngine, _razorPageActivator, pageContext.PageStarts, result.Page, _htmlEncoder);
|
||||||
|
return ExecuteAsync(pageContext, result.ContentType, result.StatusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Mvc.Core.Internal;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc.Internal;
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|
@ -304,6 +305,23 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
_page = (Page)CacheEntry.PageFactory(_pageContext);
|
_page = (Page)CacheEntry.PageFactory(_pageContext);
|
||||||
_pageContext.Page = _page;
|
_pageContext.Page = _page;
|
||||||
|
|
||||||
|
IRazorPage[] pageStarts;
|
||||||
|
|
||||||
|
if (CacheEntry.PageStartFactories == null || CacheEntry.PageStartFactories.Count == 0)
|
||||||
|
{
|
||||||
|
pageStarts = EmptyArray<IRazorPage>.Instance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pageStarts = new IRazorPage[CacheEntry.PageStartFactories.Count];
|
||||||
|
for (var i = 0; i < pageStarts.Length; i++)
|
||||||
|
{
|
||||||
|
var pageFactory = CacheEntry.PageStartFactories[i];
|
||||||
|
pageStarts[i] = pageFactory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_pageContext.PageStarts = pageStarts;
|
||||||
|
|
||||||
if (actionDescriptor.ModelTypeInfo == null)
|
if (actionDescriptor.ModelTypeInfo == null)
|
||||||
{
|
{
|
||||||
_model = _page;
|
_model = _page;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
|
|
@ -14,6 +16,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
Action<PageContext, object> releasePage,
|
Action<PageContext, object> releasePage,
|
||||||
Func<PageContext, object> modelFactory,
|
Func<PageContext, object> modelFactory,
|
||||||
Action<PageContext, object> releaseModel,
|
Action<PageContext, object> releaseModel,
|
||||||
|
IReadOnlyList<Func<IRazorPage>> pageStartFactories,
|
||||||
FilterItem[] cacheableFilters)
|
FilterItem[] cacheableFilters)
|
||||||
{
|
{
|
||||||
ActionDescriptor = actionDescriptor;
|
ActionDescriptor = actionDescriptor;
|
||||||
|
|
@ -21,6 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
ReleasePage = releasePage;
|
ReleasePage = releasePage;
|
||||||
ModelFactory = modelFactory;
|
ModelFactory = modelFactory;
|
||||||
ReleaseModel = releaseModel;
|
ReleaseModel = releaseModel;
|
||||||
|
PageStartFactories = pageStartFactories;
|
||||||
CacheableFilters = cacheableFilters;
|
CacheableFilters = cacheableFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,6 +39,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
public Func<PageContext, object> ModelFactory { get; }
|
public Func<PageContext, object> ModelFactory { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the applicable PageStarts.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<Func<IRazorPage>> PageStartFactories { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The action invoked to release a model. This may be <c>null</c>.
|
/// The action invoked to release a model. This may be <c>null</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,10 @@ using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Mvc.Internal;
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
|
|
@ -21,10 +23,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
public class PageActionInvokerProvider : IActionInvokerProvider
|
public class PageActionInvokerProvider : IActionInvokerProvider
|
||||||
{
|
{
|
||||||
|
private const string PageStartFileName = "_PageStart.cshtml";
|
||||||
private const string ModelPropertyName = "Model";
|
private const string ModelPropertyName = "Model";
|
||||||
private readonly IPageLoader _loader;
|
private readonly IPageLoader _loader;
|
||||||
private readonly IPageFactoryProvider _pageFactoryProvider;
|
private readonly IPageFactoryProvider _pageFactoryProvider;
|
||||||
private readonly IPageModelFactoryProvider _modelFactoryProvider;
|
private readonly IPageModelFactoryProvider _modelFactoryProvider;
|
||||||
|
private readonly IRazorPageFactoryProvider _razorPageFactoryProvider;
|
||||||
private readonly IActionDescriptorCollectionProvider _collectionProvider;
|
private readonly IActionDescriptorCollectionProvider _collectionProvider;
|
||||||
private readonly IFilterProvider[] _filterProviders;
|
private readonly IFilterProvider[] _filterProviders;
|
||||||
private readonly IReadOnlyList<IValueProviderFactory> _valueProviderFactories;
|
private readonly IReadOnlyList<IValueProviderFactory> _valueProviderFactories;
|
||||||
|
|
@ -32,6 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
private readonly ITempDataDictionaryFactory _tempDataFactory;
|
private readonly ITempDataDictionaryFactory _tempDataFactory;
|
||||||
private readonly HtmlHelperOptions _htmlHelperOptions;
|
private readonly HtmlHelperOptions _htmlHelperOptions;
|
||||||
private readonly IPageHandlerMethodSelector _selector;
|
private readonly IPageHandlerMethodSelector _selector;
|
||||||
|
private readonly RazorProject _razorProject;
|
||||||
private readonly DiagnosticSource _diagnosticSource;
|
private readonly DiagnosticSource _diagnosticSource;
|
||||||
private readonly ILogger<PageActionInvoker> _logger;
|
private readonly ILogger<PageActionInvoker> _logger;
|
||||||
private volatile InnerCache _currentCache;
|
private volatile InnerCache _currentCache;
|
||||||
|
|
@ -40,6 +45,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
IPageLoader loader,
|
IPageLoader loader,
|
||||||
IPageFactoryProvider pageFactoryProvider,
|
IPageFactoryProvider pageFactoryProvider,
|
||||||
IPageModelFactoryProvider modelFactoryProvider,
|
IPageModelFactoryProvider modelFactoryProvider,
|
||||||
|
IRazorPageFactoryProvider razorPageFactoryProvider,
|
||||||
IActionDescriptorCollectionProvider collectionProvider,
|
IActionDescriptorCollectionProvider collectionProvider,
|
||||||
IEnumerable<IFilterProvider> filterProviders,
|
IEnumerable<IFilterProvider> filterProviders,
|
||||||
IEnumerable<IValueProviderFactory> valueProviderFactories,
|
IEnumerable<IValueProviderFactory> valueProviderFactories,
|
||||||
|
|
@ -47,12 +53,14 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
ITempDataDictionaryFactory tempDataFactory,
|
ITempDataDictionaryFactory tempDataFactory,
|
||||||
IOptions<HtmlHelperOptions> htmlHelperOptions,
|
IOptions<HtmlHelperOptions> htmlHelperOptions,
|
||||||
IPageHandlerMethodSelector selector,
|
IPageHandlerMethodSelector selector,
|
||||||
|
RazorProject razorProject,
|
||||||
DiagnosticSource diagnosticSource,
|
DiagnosticSource diagnosticSource,
|
||||||
ILoggerFactory loggerFactory)
|
ILoggerFactory loggerFactory)
|
||||||
{
|
{
|
||||||
_loader = loader;
|
_loader = loader;
|
||||||
_pageFactoryProvider = pageFactoryProvider;
|
_pageFactoryProvider = pageFactoryProvider;
|
||||||
_modelFactoryProvider = modelFactoryProvider;
|
_modelFactoryProvider = modelFactoryProvider;
|
||||||
|
_razorPageFactoryProvider = razorPageFactoryProvider;
|
||||||
_collectionProvider = collectionProvider;
|
_collectionProvider = collectionProvider;
|
||||||
_filterProviders = filterProviders.ToArray();
|
_filterProviders = filterProviders.ToArray();
|
||||||
_valueProviderFactories = valueProviderFactories.ToArray();
|
_valueProviderFactories = valueProviderFactories.ToArray();
|
||||||
|
|
@ -60,6 +68,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
_tempDataFactory = tempDataFactory;
|
_tempDataFactory = tempDataFactory;
|
||||||
_htmlHelperOptions = htmlHelperOptions.Value;
|
_htmlHelperOptions = htmlHelperOptions.Value;
|
||||||
_selector = selector;
|
_selector = selector;
|
||||||
|
_razorProject = razorProject;
|
||||||
_diagnosticSource = diagnosticSource;
|
_diagnosticSource = diagnosticSource;
|
||||||
_logger = loggerFactory.CreateLogger<PageActionInvoker>();
|
_logger = loggerFactory.CreateLogger<PageActionInvoker>();
|
||||||
}
|
}
|
||||||
|
|
@ -171,15 +180,34 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
modelReleaser = _modelFactoryProvider.CreateModelDisposer(compiledActionDescriptor);
|
modelReleaser = _modelFactoryProvider.CreateModelDisposer(compiledActionDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pageStartFactories = GetPageStartFactories(compiledActionDescriptor);
|
||||||
|
|
||||||
return new PageActionInvokerCacheEntry(
|
return new PageActionInvokerCacheEntry(
|
||||||
compiledActionDescriptor,
|
compiledActionDescriptor,
|
||||||
pageFactory,
|
pageFactory,
|
||||||
pageDisposer,
|
pageDisposer,
|
||||||
modelFactory,
|
modelFactory,
|
||||||
modelReleaser,
|
modelReleaser,
|
||||||
|
pageStartFactories,
|
||||||
cachedFilters);
|
cachedFilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Func<IRazorPage>> GetPageStartFactories(CompiledPageActionDescriptor descriptor)
|
||||||
|
{
|
||||||
|
var pageStartFactories = new List<Func<IRazorPage>>();
|
||||||
|
var pageStartItems = _razorProject.FindHierarchicalItems(descriptor.ViewEnginePath, PageStartFileName);
|
||||||
|
foreach (var item in pageStartItems)
|
||||||
|
{
|
||||||
|
var factoryResult = _razorPageFactoryProvider.CreateFactory(item.Path);
|
||||||
|
if (factoryResult.Success)
|
||||||
|
{
|
||||||
|
pageStartFactories.Insert(0, factoryResult.RazorPageFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pageStartFactories;
|
||||||
|
}
|
||||||
|
|
||||||
private class InnerCache
|
private class InnerCache
|
||||||
{
|
{
|
||||||
public InnerCache(int version)
|
public InnerCache(int version)
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|
||||||
{
|
|
||||||
public class PageResultExecutor
|
|
||||||
{
|
|
||||||
public virtual Task ExecuteAsync(PageContext pageContext, PageViewResult result)
|
|
||||||
{
|
|
||||||
if (result.Model != null)
|
|
||||||
{
|
|
||||||
result.Page.PageContext.ViewData.Model = result.Model;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,10 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||||
|
|
@ -72,5 +75,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
_page = value;
|
_page = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the applicable _PageStart instances.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<IRazorPage> PageStarts { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Internal;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.Internal;
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
|
|
@ -10,7 +11,6 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
|
|
@ -25,8 +25,6 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly string DefaultContentType = "text/html; charset=utf-8";
|
public static readonly string DefaultContentType = "text/html; charset=utf-8";
|
||||||
|
|
||||||
private readonly IModelMetadataProvider _modelMetadataProvider;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="ViewExecutor"/>.
|
/// Creates a new <see cref="ViewExecutor"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -43,22 +41,13 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
ITempDataDictionaryFactory tempDataFactory,
|
ITempDataDictionaryFactory tempDataFactory,
|
||||||
DiagnosticSource diagnosticSource,
|
DiagnosticSource diagnosticSource,
|
||||||
IModelMetadataProvider modelMetadataProvider)
|
IModelMetadataProvider modelMetadataProvider)
|
||||||
|
: this(writerFactory, viewEngine, diagnosticSource)
|
||||||
{
|
{
|
||||||
if (viewOptions == null)
|
if (viewOptions == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(viewOptions));
|
throw new ArgumentNullException(nameof(viewOptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writerFactory == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(writerFactory));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewEngine == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(viewEngine));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tempDataFactory == null)
|
if (tempDataFactory == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(tempDataFactory));
|
throw new ArgumentNullException(nameof(tempDataFactory));
|
||||||
|
|
@ -69,17 +58,40 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
throw new ArgumentNullException(nameof(diagnosticSource));
|
throw new ArgumentNullException(nameof(diagnosticSource));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modelMetadataProvider == null)
|
ViewOptions = viewOptions.Value;
|
||||||
|
TempDataFactory = tempDataFactory;
|
||||||
|
ModelMetadataProvider = modelMetadataProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="ViewExecutor"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="writerFactory">The <see cref="IHttpResponseStreamWriterFactory"/>.</param>
|
||||||
|
/// <param name="viewEngine">The <see cref="ICompositeViewEngine"/>.</param>
|
||||||
|
/// <param name="diagnosticSource">The <see cref="System.Diagnostics.DiagnosticSource"/>.</param>
|
||||||
|
protected ViewExecutor(
|
||||||
|
IHttpResponseStreamWriterFactory writerFactory,
|
||||||
|
ICompositeViewEngine viewEngine,
|
||||||
|
DiagnosticSource diagnosticSource)
|
||||||
|
{
|
||||||
|
if (writerFactory == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(modelMetadataProvider));
|
throw new ArgumentNullException(nameof(writerFactory));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewEngine == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(viewEngine));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diagnosticSource == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(diagnosticSource));
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewOptions = viewOptions.Value;
|
|
||||||
WriterFactory = writerFactory;
|
WriterFactory = writerFactory;
|
||||||
ViewEngine = viewEngine;
|
ViewEngine = viewEngine;
|
||||||
TempDataFactory = tempDataFactory;
|
|
||||||
DiagnosticSource = diagnosticSource;
|
DiagnosticSource = diagnosticSource;
|
||||||
_modelMetadataProvider = modelMetadataProvider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -102,6 +114,11 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected MvcViewOptions ViewOptions { get; }
|
protected MvcViewOptions ViewOptions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="IModelMetadataProvider"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected IModelMetadataProvider ModelMetadataProvider { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="IHttpResponseStreamWriterFactory"/>.
|
/// Gets the <see cref="IHttpResponseStreamWriterFactory"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -140,9 +157,24 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
throw new ArgumentNullException(nameof(view));
|
throw new ArgumentNullException(nameof(view));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ViewOptions == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(Resources.FormatPropertyOfTypeCannotBeNull(nameof(ViewOptions), GetType().Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TempDataFactory == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(Resources.FormatPropertyOfTypeCannotBeNull(nameof(TempDataFactory), GetType().Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModelMetadataProvider == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(Resources.FormatPropertyOfTypeCannotBeNull(nameof(ModelMetadataProvider), GetType().Name));
|
||||||
|
}
|
||||||
|
|
||||||
if (viewData == null)
|
if (viewData == null)
|
||||||
{
|
{
|
||||||
viewData = new ViewDataDictionary(_modelMetadataProvider, actionContext.ModelState);
|
viewData = new ViewDataDictionary(ModelMetadataProvider, actionContext.ModelState);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempData == null)
|
if (tempData == null)
|
||||||
|
|
@ -150,7 +182,40 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
tempData = TempDataFactory.GetTempData(actionContext.HttpContext);
|
tempData = TempDataFactory.GetTempData(actionContext.HttpContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = actionContext.HttpContext.Response;
|
var viewContext = new ViewContext(
|
||||||
|
actionContext,
|
||||||
|
view,
|
||||||
|
viewData,
|
||||||
|
tempData,
|
||||||
|
TextWriter.Null,
|
||||||
|
ViewOptions.HtmlHelperOptions);
|
||||||
|
|
||||||
|
await ExecuteAsync(viewContext, contentType, statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a view asynchronously.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="viewContext">The <see cref="ViewContext"/> associated with the current request.</param>
|
||||||
|
/// <param name="contentType">
|
||||||
|
/// The content-type header value to set in the response. If <c>null</c>,
|
||||||
|
/// <see cref="DefaultContentType"/> will be used.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="statusCode">
|
||||||
|
/// The HTTP status code to set in the response. May be <c>null</c>.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>A <see cref="Task"/> which will complete when view execution is completed.</returns>
|
||||||
|
protected async Task ExecuteAsync(
|
||||||
|
ViewContext viewContext,
|
||||||
|
string contentType,
|
||||||
|
int? statusCode)
|
||||||
|
{
|
||||||
|
if (viewContext == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(viewContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = viewContext.HttpContext.Response;
|
||||||
|
|
||||||
string resolvedContentType = null;
|
string resolvedContentType = null;
|
||||||
Encoding resolvedContentTypeEncoding = null;
|
Encoding resolvedContentTypeEncoding = null;
|
||||||
|
|
@ -170,19 +235,23 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
|
|
||||||
using (var writer = WriterFactory.CreateWriter(response.Body, resolvedContentTypeEncoding))
|
using (var writer = WriterFactory.CreateWriter(response.Body, resolvedContentTypeEncoding))
|
||||||
{
|
{
|
||||||
var viewContext = new ViewContext(
|
var view = viewContext.View;
|
||||||
actionContext,
|
|
||||||
view,
|
|
||||||
viewData,
|
|
||||||
tempData,
|
|
||||||
writer,
|
|
||||||
ViewOptions.HtmlHelperOptions);
|
|
||||||
|
|
||||||
DiagnosticSource.BeforeView(view, viewContext);
|
var oldWriter = viewContext.Writer;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
viewContext.Writer = writer;
|
||||||
|
|
||||||
await view.RenderAsync(viewContext);
|
DiagnosticSource.BeforeView(view, viewContext);
|
||||||
|
|
||||||
DiagnosticSource.AfterView(view, viewContext);
|
await view.RenderAsync(viewContext);
|
||||||
|
|
||||||
|
DiagnosticSource.AfterView(view, viewContext);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
viewContext.Writer = oldWriter;
|
||||||
|
}
|
||||||
|
|
||||||
// Perf: Invoke FlushAsync to ensure any buffered content is asynchronously written to the underlying
|
// Perf: Invoke FlushAsync to ensure any buffered content is asynchronously written to the underlying
|
||||||
// response asynchronously. In the absence of this line, the buffer gets synchronously written to the
|
// response asynchronously. In the absence of this line, the buffer gets synchronously written to the
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,14 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
using Microsoft.AspNetCore.Razor.Evolution;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.Extensions.Logging.Testing;
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -120,6 +124,53 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
Assert.Same(modelDisposer, entry.ReleaseModel);
|
Assert.Same(modelDisposer, entry.ReleaseModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void OnProvidersExecuting_CachesViewStartFactories()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var descriptor = new PageActionDescriptor
|
||||||
|
{
|
||||||
|
RelativePath = "/Home/Path1/File.cshtml",
|
||||||
|
ViewEnginePath = "/Home/Path1/File.cshtml",
|
||||||
|
FilterDescriptors = new FilterDescriptor[0],
|
||||||
|
};
|
||||||
|
|
||||||
|
var loader = new Mock<IPageLoader>();
|
||||||
|
loader.Setup(l => l.Load(It.IsAny<PageActionDescriptor>()))
|
||||||
|
.Returns(typeof(PageWithModel));
|
||||||
|
var descriptorCollection = new ActionDescriptorCollection(new[] { descriptor }, version: 1);
|
||||||
|
var actionDescriptorProvider = new Mock<IActionDescriptorCollectionProvider>();
|
||||||
|
actionDescriptorProvider.Setup(p => p.ActionDescriptors).Returns(descriptorCollection);
|
||||||
|
var razorPageFactoryProvider = new Mock<IRazorPageFactoryProvider>();
|
||||||
|
Func<IRazorPage> factory1 = () => null;
|
||||||
|
Func<IRazorPage> factory2 = () => null;
|
||||||
|
razorPageFactoryProvider.Setup(f => f.CreateFactory("/Home/Path1/_PageStart.cshtml"))
|
||||||
|
.Returns(new RazorPageFactoryResult(factory1, new IChangeToken[0]));
|
||||||
|
razorPageFactoryProvider.Setup(f => f.CreateFactory("/_PageStart.cshtml"))
|
||||||
|
.Returns(new RazorPageFactoryResult(factory2, new[] { Mock.Of<IChangeToken>() }));
|
||||||
|
var fileProvider = new TestFileProvider();
|
||||||
|
fileProvider.AddFile("/Home/Path1/_PageStart.cshtml", "content1");
|
||||||
|
fileProvider.AddFile("/_PageStart.cshtml", "content2");
|
||||||
|
var defaultRazorProject = new DefaultRazorProject(fileProvider);
|
||||||
|
|
||||||
|
var invokerProvider = CreateInvokerProvider(
|
||||||
|
loader.Object,
|
||||||
|
actionDescriptorProvider.Object,
|
||||||
|
razorPageFactoryProvider: razorPageFactoryProvider.Object,
|
||||||
|
razorProject: defaultRazorProject);
|
||||||
|
var context = new ActionInvokerProviderContext(
|
||||||
|
new ActionContext(new DefaultHttpContext(), new RouteData(), descriptor));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
invokerProvider.OnProvidersExecuting(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(context.Result);
|
||||||
|
var actionInvoker = Assert.IsType<PageActionInvoker>(context.Result);
|
||||||
|
var entry = actionInvoker.CacheEntry;
|
||||||
|
Assert.Equal(new[] { factory2, factory1 }, entry.PageStartFactories);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void OnProvidersExecuting_CachesEntries()
|
public void OnProvidersExecuting_CachesEntries()
|
||||||
{
|
{
|
||||||
|
|
@ -207,16 +258,24 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
IPageLoader loader,
|
IPageLoader loader,
|
||||||
IActionDescriptorCollectionProvider actionDescriptorProvider,
|
IActionDescriptorCollectionProvider actionDescriptorProvider,
|
||||||
IPageFactoryProvider pageProvider = null,
|
IPageFactoryProvider pageProvider = null,
|
||||||
IPageModelFactoryProvider modelProvider = null)
|
IPageModelFactoryProvider modelProvider = null,
|
||||||
|
IRazorPageFactoryProvider razorPageFactoryProvider = null,
|
||||||
|
RazorProject razorProject = null)
|
||||||
{
|
{
|
||||||
var tempDataFactory = new Mock<ITempDataDictionaryFactory>();
|
var tempDataFactory = new Mock<ITempDataDictionaryFactory>();
|
||||||
tempDataFactory.Setup(t => t.GetTempData(It.IsAny<HttpContext>()))
|
tempDataFactory.Setup(t => t.GetTempData(It.IsAny<HttpContext>()))
|
||||||
.Returns((HttpContext context) => new TempDataDictionary(context, Mock.Of<ITempDataProvider>()));
|
.Returns((HttpContext context) => new TempDataDictionary(context, Mock.Of<ITempDataProvider>()));
|
||||||
|
|
||||||
|
if (razorProject == null)
|
||||||
|
{
|
||||||
|
razorProject = Mock.Of<RazorProject>();
|
||||||
|
}
|
||||||
|
|
||||||
return new PageActionInvokerProvider(
|
return new PageActionInvokerProvider(
|
||||||
loader,
|
loader,
|
||||||
pageProvider ?? Mock.Of<IPageFactoryProvider>(),
|
pageProvider ?? Mock.Of<IPageFactoryProvider>(),
|
||||||
modelProvider ?? Mock.Of<IPageModelFactoryProvider>(),
|
modelProvider ?? Mock.Of<IPageModelFactoryProvider>(),
|
||||||
|
razorPageFactoryProvider ?? Mock.Of<IRazorPageFactoryProvider>(),
|
||||||
actionDescriptorProvider,
|
actionDescriptorProvider,
|
||||||
new IFilterProvider[0],
|
new IFilterProvider[0],
|
||||||
new IValueProviderFactory[0],
|
new IValueProviderFactory[0],
|
||||||
|
|
@ -224,6 +283,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
tempDataFactory.Object,
|
tempDataFactory.Object,
|
||||||
new TestOptionsManager<HtmlHelperOptions>(),
|
new TestOptionsManager<HtmlHelperOptions>(),
|
||||||
Mock.Of<IPageHandlerMethodSelector>(),
|
Mock.Of<IPageHandlerMethodSelector>(),
|
||||||
|
razorProject,
|
||||||
new DiagnosticListener("Microsoft.AspNetCore"),
|
new DiagnosticListener("Microsoft.AspNetCore"),
|
||||||
NullLoggerFactory.Instance);
|
NullLoggerFactory.Instance);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,15 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
@ -346,6 +350,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
null,
|
null,
|
||||||
(context) => null,
|
(context) => null,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
new FilterItem[0]);
|
new FilterItem[0]);
|
||||||
var invoker = CreateInvoker(
|
var invoker = CreateInvoker(
|
||||||
new[] { filter1.Object, filter2.Object, filter3.Object },
|
new[] { filter1.Object, filter2.Object, filter3.Object },
|
||||||
|
|
@ -399,6 +404,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
null,
|
null,
|
||||||
(context) => null,
|
(context) => null,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
new FilterItem[0]);
|
new FilterItem[0]);
|
||||||
var invoker = CreateInvoker(
|
var invoker = CreateInvoker(
|
||||||
new IFilterMetadata[] { filter1.Object, filter2.Object, filter3.Object },
|
new IFilterMetadata[] { filter1.Object, filter2.Object, filter3.Object },
|
||||||
|
|
@ -530,12 +536,24 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
int maxAllowedErrorsInModelState = 200,
|
int maxAllowedErrorsInModelState = 200,
|
||||||
List<IValueProviderFactory> valueProviderFactories = null,
|
List<IValueProviderFactory> valueProviderFactories = null,
|
||||||
RouteData routeData = null,
|
RouteData routeData = null,
|
||||||
ILogger logger = null,
|
ILogger logger = null)
|
||||||
object diagnosticListener = null)
|
|
||||||
{
|
{
|
||||||
|
var diagnosticSource = new DiagnosticListener("Microsoft.AspNetCore");
|
||||||
|
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
var serviceCollection = new ServiceCollection();
|
var serviceCollection = new ServiceCollection();
|
||||||
serviceCollection.AddSingleton(executor ?? new PageResultExecutor());
|
if (executor == null)
|
||||||
|
{
|
||||||
|
executor = new PageResultExecutor(
|
||||||
|
Mock.Of<IHttpResponseStreamWriterFactory>(),
|
||||||
|
Mock.Of<ICompositeViewEngine>(),
|
||||||
|
Mock.Of<IRazorViewEngine>(),
|
||||||
|
Mock.Of<IRazorPageActivator>(),
|
||||||
|
diagnosticSource,
|
||||||
|
HtmlEncoder.Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceCollection.AddSingleton(executor ?? executor);
|
||||||
httpContext.RequestServices = serviceCollection.BuildServiceProvider();
|
httpContext.RequestServices = serviceCollection.BuildServiceProvider();
|
||||||
|
|
||||||
if (routeData == null)
|
if (routeData == null)
|
||||||
|
|
@ -584,8 +602,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
(c, page) => { (page as IDisposable)?.Dispose(); },
|
(c, page) => { (page as IDisposable)?.Dispose(); },
|
||||||
_ => Activator.CreateInstance(actionDescriptor.ModelTypeInfo.AsType()),
|
_ => Activator.CreateInstance(actionDescriptor.ModelTypeInfo.AsType()),
|
||||||
(c, model) => { (model as IDisposable)?.Dispose(); },
|
(c, model) => { (model as IDisposable)?.Dispose(); },
|
||||||
|
null,
|
||||||
new FilterItem[0]);
|
new FilterItem[0]);
|
||||||
var diagnosticSource = new DiagnosticListener("Microsoft.AspNetCore");
|
|
||||||
|
|
||||||
var invoker = new PageActionInvoker(
|
var invoker = new PageActionInvoker(
|
||||||
selector,
|
selector,
|
||||||
|
|
@ -603,6 +621,13 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
private readonly Func<PageContext, Task> _executeAction;
|
private readonly Func<PageContext, Task> _executeAction;
|
||||||
|
|
||||||
public TestPageResultExecutor(Func<PageContext, Task> executeAction)
|
public TestPageResultExecutor(Func<PageContext, Task> executeAction)
|
||||||
|
: base(
|
||||||
|
Mock.Of<IHttpResponseStreamWriterFactory>(),
|
||||||
|
Mock.Of<ICompositeViewEngine>(),
|
||||||
|
Mock.Of<IRazorViewEngine>(),
|
||||||
|
Mock.Of<IRazorPageActivator>(),
|
||||||
|
new DiagnosticListener("Microsoft.AspNetCore"),
|
||||||
|
HtmlEncoder.Default)
|
||||||
{
|
{
|
||||||
_executeAction = executeAction;
|
_executeAction = executeAction;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue