Separate PageContext and ViewContext
This change decouples PageContext and ViewContext completely.
This commit is contained in:
parent
6094c6ff52
commit
2992f8e38a
|
|
@ -1285,7 +1285,7 @@ namespace Microsoft.AspNetCore.Mvc.Core
|
||||||
=> string.Format(CultureInfo.CurrentCulture, GetString("NoRoutesMatchedForPage"), p0);
|
=> string.Format(CultureInfo.CurrentCulture, GetString("NoRoutesMatchedForPage"), p0);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The relative page path '{0}' can only can only be used while executing a Razor Page. Specify a root relative path with a leading '/' to generate a URL outside of a Razor Page.
|
/// The relative page path '{0}' can only be used while executing a Razor Page. Specify a root relative path with a leading '/' to generate a URL outside of a Razor Page.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string UrlHelper_RelativePagePathIsNotSupported
|
internal static string UrlHelper_RelativePagePathIsNotSupported
|
||||||
{
|
{
|
||||||
|
|
@ -1293,7 +1293,7 @@ namespace Microsoft.AspNetCore.Mvc.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The relative page path '{0}' can only can only be used while executing a Razor Page. Specify a root relative path with a leading '/' to generate a URL outside of a Razor Page.
|
/// The relative page path '{0}' can only be used while executing a Razor Page. Specify a root relative path with a leading '/' to generate a URL outside of a Razor Page.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string FormatUrlHelper_RelativePagePathIsNotSupported(object p0)
|
internal static string FormatUrlHelper_RelativePagePathIsNotSupported(object p0)
|
||||||
=> string.Format(CultureInfo.CurrentCulture, GetString("UrlHelper_RelativePagePathIsNotSupported"), p0);
|
=> string.Format(CultureInfo.CurrentCulture, GetString("UrlHelper_RelativePagePathIsNotSupported"), p0);
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
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.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Internal;
|
using Microsoft.Extensions.Internal;
|
||||||
|
|
||||||
|
|
@ -16,8 +16,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
{
|
{
|
||||||
public class RazorPagePropertyActivator
|
public class RazorPagePropertyActivator
|
||||||
{
|
{
|
||||||
private delegate ViewDataDictionary CreateViewDataNestedDelegate(ViewDataDictionary source);
|
private readonly IModelMetadataProvider _metadataProvider;
|
||||||
private delegate ViewDataDictionary CreateViewDataRootDelegate(ModelStateDictionary modelState);
|
private readonly Func<IModelMetadataProvider, ModelStateDictionary, ViewDataDictionary> _rootFactory;
|
||||||
|
private readonly Func<ViewDataDictionary, ViewDataDictionary> _nestedFactory;
|
||||||
|
private readonly Type _viewDataDictionaryType;
|
||||||
|
private readonly PropertyActivator<ViewContext>[] _propertyActivators;
|
||||||
|
|
||||||
public RazorPagePropertyActivator(
|
public RazorPagePropertyActivator(
|
||||||
Type pageType,
|
Type pageType,
|
||||||
|
|
@ -25,26 +28,19 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
IModelMetadataProvider metadataProvider,
|
IModelMetadataProvider metadataProvider,
|
||||||
PropertyValueAccessors propertyValueAccessors)
|
PropertyValueAccessors propertyValueAccessors)
|
||||||
{
|
{
|
||||||
var viewDataType = typeof(ViewDataDictionary<>).MakeGenericType(modelType);
|
_metadataProvider = metadataProvider;
|
||||||
ViewDataDictionaryType = viewDataType;
|
|
||||||
CreateViewDataNested = GetCreateViewDataNested(viewDataType);
|
|
||||||
CreateViewDataRoot = GetCreateViewDataRoot(viewDataType, metadataProvider);
|
|
||||||
|
|
||||||
PropertyActivators = PropertyActivator<ViewContext>.GetPropertiesToActivate(
|
_viewDataDictionaryType = typeof(ViewDataDictionary<>).MakeGenericType(modelType);
|
||||||
|
_rootFactory = ViewDataDictionaryFactory.CreateFactory(modelType.GetTypeInfo());
|
||||||
|
_nestedFactory = ViewDataDictionaryFactory.CreateNestedFactory(modelType.GetTypeInfo());
|
||||||
|
|
||||||
|
_propertyActivators = PropertyActivator<ViewContext>.GetPropertiesToActivate(
|
||||||
pageType,
|
pageType,
|
||||||
typeof(RazorInjectAttribute),
|
typeof(RazorInjectAttribute),
|
||||||
propertyInfo => CreateActivateInfo(propertyInfo, propertyValueAccessors),
|
propertyInfo => CreateActivateInfo(propertyInfo, propertyValueAccessors),
|
||||||
includeNonPublic: true);
|
includeNonPublic: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyActivator<ViewContext>[] PropertyActivators { get; }
|
|
||||||
|
|
||||||
private Type ViewDataDictionaryType { get; }
|
|
||||||
|
|
||||||
private CreateViewDataNestedDelegate CreateViewDataNested { get; }
|
|
||||||
|
|
||||||
private CreateViewDataRootDelegate CreateViewDataRoot { get; }
|
|
||||||
|
|
||||||
public void Activate(object page, ViewContext context)
|
public void Activate(object page, ViewContext context)
|
||||||
{
|
{
|
||||||
if (context == null)
|
if (context == null)
|
||||||
|
|
@ -54,9 +50,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
|
|
||||||
context.ViewData = CreateViewDataDictionary(context);
|
context.ViewData = CreateViewDataDictionary(context);
|
||||||
|
|
||||||
for (var i = 0; i < PropertyActivators.Length; i++)
|
for (var i = 0; i < _propertyActivators.Length; i++)
|
||||||
{
|
{
|
||||||
var activateInfo = PropertyActivators[i];
|
var activateInfo = _propertyActivators[i];
|
||||||
activateInfo.Activate(page, context);
|
activateInfo.Activate(page, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,58 +64,17 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
||||||
if (context.ViewData == null)
|
if (context.ViewData == null)
|
||||||
{
|
{
|
||||||
// Create ViewDataDictionary<TModel>(IModelMetadataProvider, ModelStateDictionary).
|
// Create ViewDataDictionary<TModel>(IModelMetadataProvider, ModelStateDictionary).
|
||||||
return CreateViewDataRoot(context.ModelState);
|
return _rootFactory(_metadataProvider, context.ModelState);
|
||||||
}
|
}
|
||||||
else if (context.ViewData.GetType() != ViewDataDictionaryType)
|
else if (context.ViewData.GetType() != _viewDataDictionaryType)
|
||||||
{
|
{
|
||||||
// Create ViewDataDictionary<TModel>(ViewDataDictionary).
|
// Create ViewDataDictionary<TModel>(ViewDataDictionary).
|
||||||
return CreateViewDataNested(context.ViewData);
|
return _nestedFactory(context.ViewData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.ViewData;
|
return context.ViewData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CreateViewDataNestedDelegate GetCreateViewDataNested(Type viewDataDictionaryType)
|
|
||||||
{
|
|
||||||
var parameterTypes = new Type[] { typeof(ViewDataDictionary) };
|
|
||||||
var matchingConstructor = viewDataDictionaryType.GetConstructor(parameterTypes);
|
|
||||||
Debug.Assert(matchingConstructor != null);
|
|
||||||
|
|
||||||
var parameters = new ParameterExpression[] { Expression.Parameter(parameterTypes[0]) };
|
|
||||||
var newExpression = Expression.New(matchingConstructor, parameters);
|
|
||||||
var castNewCall = Expression.Convert(
|
|
||||||
newExpression,
|
|
||||||
typeof(ViewDataDictionary));
|
|
||||||
var lambda = Expression.Lambda<CreateViewDataNestedDelegate>(castNewCall, parameters);
|
|
||||||
return lambda.Compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static CreateViewDataRootDelegate GetCreateViewDataRoot(
|
|
||||||
Type viewDataDictionaryType,
|
|
||||||
IModelMetadataProvider provider)
|
|
||||||
{
|
|
||||||
var parameterTypes = new[]
|
|
||||||
{
|
|
||||||
typeof(IModelMetadataProvider),
|
|
||||||
typeof(ModelStateDictionary)
|
|
||||||
};
|
|
||||||
var matchingConstructor = viewDataDictionaryType.GetConstructor(parameterTypes);
|
|
||||||
Debug.Assert(matchingConstructor != null);
|
|
||||||
|
|
||||||
var parameterExpression = Expression.Parameter(parameterTypes[1]);
|
|
||||||
var parameters = new Expression[]
|
|
||||||
{
|
|
||||||
Expression.Constant(provider),
|
|
||||||
parameterExpression
|
|
||||||
};
|
|
||||||
var newExpression = Expression.New(matchingConstructor, parameters);
|
|
||||||
var castNewCall = Expression.Convert(
|
|
||||||
newExpression,
|
|
||||||
typeof(ViewDataDictionary));
|
|
||||||
var lambda = Expression.Lambda<CreateViewDataRootDelegate>(castNewCall, parameterExpression);
|
|
||||||
return lambda.Compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PropertyActivator<ViewContext> CreateActivateInfo(
|
private static PropertyActivator<ViewContext> CreateActivateInfo(
|
||||||
PropertyInfo property,
|
PropertyInfo property,
|
||||||
PropertyValueAccessors valueAccessors)
|
PropertyValueAccessors valueAccessors)
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
services.TryAddSingleton<IPageModelActivatorProvider, DefaultPageModelActivatorProvider>();
|
services.TryAddSingleton<IPageModelActivatorProvider, DefaultPageModelActivatorProvider>();
|
||||||
services.TryAddSingleton<IPageModelFactoryProvider, DefaultPageModelFactoryProvider>();
|
services.TryAddSingleton<IPageModelFactoryProvider, DefaultPageModelFactoryProvider>();
|
||||||
|
|
||||||
services.TryAddSingleton<IPageActivatorProvider, DefaultPageActivator>();
|
services.TryAddSingleton<IPageActivatorProvider, DefaultPageActivatorProvider>();
|
||||||
services.TryAddSingleton<IPageFactoryProvider, DefaultPageFactory>();
|
services.TryAddSingleton<IPageFactoryProvider, DefaultPageFactory>();
|
||||||
|
|
||||||
services.TryAddSingleton<IPageLoader, DefaultPageLoader>();
|
services.TryAddSingleton<IPageLoader, DefaultPageLoader>();
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// 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 Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
{
|
{
|
||||||
|
|
@ -15,13 +16,13 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="descriptor">The <see cref="CompiledPageActionDescriptor"/>.</param>
|
/// <param name="descriptor">The <see cref="CompiledPageActionDescriptor"/>.</param>
|
||||||
/// <returns>The delegate used to activate the page.</returns>
|
/// <returns>The delegate used to activate the page.</returns>
|
||||||
Func<PageContext, object> CreateActivator(CompiledPageActionDescriptor descriptor);
|
Func<PageContext, ViewContext, object> CreateActivator(CompiledPageActionDescriptor descriptor);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases a Razor page.
|
/// Releases a Razor page.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="descriptor">The <see cref="CompiledPageActionDescriptor"/>.</param>
|
/// <param name="descriptor">The <see cref="CompiledPageActionDescriptor"/>.</param>
|
||||||
/// <returns>The delegate used to dispose the activated page.</returns>
|
/// <returns>The delegate used to dispose the activated page.</returns>
|
||||||
Action<PageContext, object> CreateReleaser(CompiledPageActionDescriptor descriptor);
|
Action<PageContext, ViewContext, object> CreateReleaser(CompiledPageActionDescriptor descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// 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 Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
{
|
{
|
||||||
|
|
@ -15,13 +16,13 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="descriptor">The <see cref="CompiledPageActionDescriptor"/>.</param>
|
/// <param name="descriptor">The <see cref="CompiledPageActionDescriptor"/>.</param>
|
||||||
/// <returns>The Razor page factory.</returns>
|
/// <returns>The Razor page factory.</returns>
|
||||||
Func<PageContext, object> CreatePageFactory(CompiledPageActionDescriptor descriptor);
|
Func<PageContext, ViewContext, object> CreatePageFactory(CompiledPageActionDescriptor descriptor);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases a Razor page.
|
/// Releases a Razor page.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="descriptor">The <see cref="CompiledPageActionDescriptor"/>.</param>
|
/// <param name="descriptor">The <see cref="CompiledPageActionDescriptor"/>.</param>
|
||||||
/// <returns>The delegate used to release the created page.</returns>
|
/// <returns>The delegate used to release the created page.</returns>
|
||||||
Action<PageContext, object> CreatePageDisposer(CompiledPageActionDescriptor descriptor);
|
Action<PageContext, ViewContext, object> CreatePageDisposer(CompiledPageActionDescriptor descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,18 +4,19 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see cref="IPageActivatorProvider"/> that uses type activation to create Pages.
|
/// <see cref="IPageActivatorProvider"/> that uses type activation to create Pages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DefaultPageActivator : IPageActivatorProvider
|
public class DefaultPageActivatorProvider : IPageActivatorProvider
|
||||||
{
|
{
|
||||||
private readonly Action<PageContext, object> _disposer = Dispose;
|
private readonly Action<PageContext, ViewContext, object> _disposer = Dispose;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual Func<PageContext, object> CreateActivator(CompiledPageActionDescriptor actionDescriptor)
|
public virtual Func<PageContext, ViewContext, object> CreateActivator(CompiledPageActionDescriptor actionDescriptor)
|
||||||
{
|
{
|
||||||
if (actionDescriptor == null)
|
if (actionDescriptor == null)
|
||||||
{
|
{
|
||||||
|
|
@ -34,7 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
return CreatePageFactory(pageTypeInfo);
|
return CreatePageFactory(pageTypeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Action<PageContext, object> CreateReleaser(CompiledPageActionDescriptor actionDescriptor)
|
public virtual Action<PageContext, ViewContext, object> CreateReleaser(CompiledPageActionDescriptor actionDescriptor)
|
||||||
{
|
{
|
||||||
if (actionDescriptor == null)
|
if (actionDescriptor == null)
|
||||||
{
|
{
|
||||||
|
|
@ -49,27 +50,33 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Func<PageContext, object> CreatePageFactory(Type pageTypeInfo)
|
private static Func<PageContext, ViewContext, object> CreatePageFactory(Type pageTypeInfo)
|
||||||
{
|
{
|
||||||
var parameter = Expression.Parameter(typeof(PageContext), "pageContext");
|
var parameter1 = Expression.Parameter(typeof(PageContext), "pageContext");
|
||||||
|
var parameter2 = Expression.Parameter(typeof(ViewContext), "viewContext");
|
||||||
|
|
||||||
// new Page();
|
// new Page();
|
||||||
var newExpression = Expression.New(pageTypeInfo);
|
var newExpression = Expression.New(pageTypeInfo);
|
||||||
|
|
||||||
// () => new Page();
|
// () => new Page();
|
||||||
var pageFactory = Expression
|
var pageFactory = Expression
|
||||||
.Lambda<Func<PageContext, object>>(newExpression, parameter)
|
.Lambda<Func<PageContext, ViewContext, object>>(newExpression, parameter1, parameter2)
|
||||||
.Compile();
|
.Compile();
|
||||||
return pageFactory;
|
return pageFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Dispose(PageContext context, object page)
|
private static void Dispose(PageContext context, ViewContext viewContext, object page)
|
||||||
{
|
{
|
||||||
if (context == null)
|
if (context == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(context));
|
throw new ArgumentNullException(nameof(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (viewContext == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(viewContext));
|
||||||
|
}
|
||||||
|
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(page));
|
throw new ArgumentNullException(nameof(page));
|
||||||
|
|
@ -77,20 +84,5 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
|
|
||||||
((IDisposable)page).Dispose();
|
((IDisposable)page).Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void NullDisposer(PageContext context, object page)
|
|
||||||
{
|
|
||||||
if (context == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (page == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(page));
|
|
||||||
}
|
|
||||||
|
|
||||||
// No-op
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Func<PageContext, object> CreatePageFactory(CompiledPageActionDescriptor actionDescriptor)
|
public virtual Func<PageContext, ViewContext, object> CreatePageFactory(CompiledPageActionDescriptor actionDescriptor)
|
||||||
{
|
{
|
||||||
if (!typeof(Page).GetTypeInfo().IsAssignableFrom(actionDescriptor.PageTypeInfo))
|
if (!typeof(Page).GetTypeInfo().IsAssignableFrom(actionDescriptor.PageTypeInfo))
|
||||||
{
|
{
|
||||||
|
|
@ -57,17 +57,18 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
_modelMetadataProvider,
|
_modelMetadataProvider,
|
||||||
_propertyAccessors);
|
_propertyAccessors);
|
||||||
|
|
||||||
return (context) =>
|
return (pageContext, viewContext) =>
|
||||||
{
|
{
|
||||||
var page = (Page)activatorFactory(context);
|
var page = (Page)activatorFactory(pageContext, viewContext);
|
||||||
page.PageContext = context;
|
page.PageContext = pageContext;
|
||||||
page.Path = context.ActionDescriptor.RelativePath;
|
page.Path = pageContext.ActionDescriptor.RelativePath;
|
||||||
propertyActivator.Activate(page, context);
|
page.ViewContext = viewContext;
|
||||||
|
propertyActivator.Activate(page, viewContext);
|
||||||
return page;
|
return page;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Action<PageContext, object> CreatePageDisposer(CompiledPageActionDescriptor descriptor)
|
public virtual Action<PageContext, ViewContext, object> CreatePageDisposer(CompiledPageActionDescriptor descriptor)
|
||||||
{
|
{
|
||||||
if (descriptor == null)
|
if (descriptor == null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.Internal;
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
|
|
@ -65,9 +66,21 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
pageContext.ViewData.Model = result.Model;
|
pageContext.ViewData.Model = result.Model;
|
||||||
}
|
}
|
||||||
|
|
||||||
var view = new RazorView(_razorViewEngine, _razorPageActivator, pageContext.ViewStarts, result.Page, _htmlEncoder);
|
var viewStarts = new IRazorPage[pageContext.ViewStartFactories.Count];
|
||||||
pageContext.View = view;
|
for (var i = 0; i < pageContext.ViewStartFactories.Count; i++)
|
||||||
return ExecuteAsync(pageContext, result.ContentType, result.StatusCode);
|
{
|
||||||
|
viewStarts[i] = pageContext.ViewStartFactories[i]();
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewContext = result.Page.ViewContext;
|
||||||
|
viewContext.View = new RazorView(
|
||||||
|
_razorViewEngine,
|
||||||
|
_razorPageActivator,
|
||||||
|
viewStarts,
|
||||||
|
result.Page,
|
||||||
|
_htmlEncoder);
|
||||||
|
|
||||||
|
return ExecuteAsync(viewContext, result.ContentType, result.StatusCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.ExceptionServices;
|
using System.Runtime.ExceptionServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -13,8 +14,11 @@ using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
|
|
@ -23,9 +27,13 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
private readonly IPageHandlerMethodSelector _selector;
|
private readonly IPageHandlerMethodSelector _selector;
|
||||||
private readonly PageContext _pageContext;
|
private readonly PageContext _pageContext;
|
||||||
private readonly ParameterBinder _parameterBinder;
|
private readonly ParameterBinder _parameterBinder;
|
||||||
|
private readonly ITempDataDictionaryFactory _tempDataFactory;
|
||||||
|
private readonly HtmlHelperOptions _htmlHelperOptions;
|
||||||
|
|
||||||
|
private CompiledPageActionDescriptor _actionDescriptor;
|
||||||
private Page _page;
|
private Page _page;
|
||||||
private object _model;
|
private object _model;
|
||||||
|
private ViewContext _viewContext;
|
||||||
private ExceptionContext _exceptionContext;
|
private ExceptionContext _exceptionContext;
|
||||||
|
|
||||||
public PageActionInvoker(
|
public PageActionInvoker(
|
||||||
|
|
@ -36,7 +44,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
IFilterMetadata[] filterMetadata,
|
IFilterMetadata[] filterMetadata,
|
||||||
IList<IValueProviderFactory> valueProviderFactories,
|
IList<IValueProviderFactory> valueProviderFactories,
|
||||||
PageActionInvokerCacheEntry cacheEntry,
|
PageActionInvokerCacheEntry cacheEntry,
|
||||||
ParameterBinder parameterBinder)
|
ParameterBinder parameterBinder,
|
||||||
|
ITempDataDictionaryFactory tempDataFactory,
|
||||||
|
HtmlHelperOptions htmlHelperOptions)
|
||||||
: base(
|
: base(
|
||||||
diagnosticSource,
|
diagnosticSource,
|
||||||
logger,
|
logger,
|
||||||
|
|
@ -48,9 +58,17 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
_pageContext = pageContext;
|
_pageContext = pageContext;
|
||||||
CacheEntry = cacheEntry;
|
CacheEntry = cacheEntry;
|
||||||
_parameterBinder = parameterBinder;
|
_parameterBinder = parameterBinder;
|
||||||
|
_tempDataFactory = tempDataFactory;
|
||||||
|
_htmlHelperOptions = htmlHelperOptions;
|
||||||
|
|
||||||
|
_actionDescriptor = pageContext.ActionDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PageActionInvokerCacheEntry CacheEntry { get; }
|
// Internal for testing
|
||||||
|
internal PageActionInvokerCacheEntry CacheEntry { get; }
|
||||||
|
|
||||||
|
// Internal for testing
|
||||||
|
internal PageContext PageContext => _pageContext;
|
||||||
|
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <see cref="ResourceInvoker"/> for details on what the variables in this method represent.
|
/// <see cref="ResourceInvoker"/> for details on what the variables in this method represent.
|
||||||
|
|
@ -77,7 +95,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
if (_page != null && CacheEntry.ReleasePage != null)
|
if (_page != null && CacheEntry.ReleasePage != null)
|
||||||
{
|
{
|
||||||
CacheEntry.ReleasePage(_pageContext, _page);
|
CacheEntry.ReleasePage(_pageContext, _viewContext, _page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,47 +321,36 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ExecutePageAsync()
|
private Task ExecutePageAsync()
|
||||||
{
|
{
|
||||||
var actionDescriptor = _pageContext.ActionDescriptor;
|
|
||||||
_page = (Page)CacheEntry.PageFactory(_pageContext);
|
|
||||||
_pageContext.Page = _page;
|
|
||||||
_pageContext.ValueProviderFactories = _valueProviderFactories;
|
_pageContext.ValueProviderFactories = _valueProviderFactories;
|
||||||
|
|
||||||
IRazorPage[] viewStarts;
|
// There's a fork in the road here between the case where we have a full-fledged PageModel
|
||||||
|
// vs just a Page. We need to know up front because we want to execute handler methods
|
||||||
if (CacheEntry.ViewStartFactories == null || CacheEntry.ViewStartFactories.Count == 0)
|
// on the PageModel without instantiating the Page or ViewContext.
|
||||||
|
var hasPageModel = _actionDescriptor.HandlerTypeInfo != _actionDescriptor.PageTypeInfo;
|
||||||
|
if (hasPageModel)
|
||||||
{
|
{
|
||||||
viewStarts = Array.Empty<IRazorPage>();
|
return ExecutePageWithPageModelAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
viewStarts = new IRazorPage[CacheEntry.ViewStartFactories.Count];
|
return ExecutePageWithoutPageModelAsync();
|
||||||
for (var i = 0; i < viewStarts.Length; i++)
|
|
||||||
{
|
|
||||||
var pageFactory = CacheEntry.ViewStartFactories[i];
|
|
||||||
viewStarts[i] = pageFactory();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_pageContext.ViewStarts = viewStarts;
|
}
|
||||||
|
|
||||||
if (actionDescriptor.ModelTypeInfo == actionDescriptor.PageTypeInfo)
|
private async Task ExecutePageWithPageModelAsync()
|
||||||
{
|
{
|
||||||
_model = _page;
|
// Since this is a PageModel, we need to activate it, and then run a handler method on the model.
|
||||||
}
|
//
|
||||||
else
|
// We also know that the model is the pagemodel at this point.
|
||||||
{
|
Debug.Assert(_actionDescriptor.ModelTypeInfo == _actionDescriptor.HandlerTypeInfo);
|
||||||
_model = CacheEntry.ModelFactory(_pageContext);
|
_model = CacheEntry.ModelFactory(_pageContext);
|
||||||
}
|
_pageContext.ViewData.Model = _model;
|
||||||
|
|
||||||
if (_model != null)
|
|
||||||
{
|
|
||||||
_pageContext.ViewData.Model = _model;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CacheEntry.PropertyBinder != null)
|
if (CacheEntry.PropertyBinder != null)
|
||||||
{
|
{
|
||||||
await CacheEntry.PropertyBinder(_page, _model);
|
await CacheEntry.PropertyBinder(_pageContext, _model);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a workaround for not yet having proper filter for Pages.
|
// This is a workaround for not yet having proper filter for Pages.
|
||||||
|
|
@ -359,44 +366,82 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
if (propertyFilter != null)
|
if (propertyFilter != null)
|
||||||
{
|
{
|
||||||
object subject = _page;
|
propertyFilter.Subject = _model;
|
||||||
|
|
||||||
if (_model != null)
|
|
||||||
{
|
|
||||||
subject = _model;
|
|
||||||
}
|
|
||||||
|
|
||||||
propertyFilter.Subject = subject;
|
|
||||||
propertyFilter.ApplyTempDataChanges(_pageContext.HttpContext);
|
propertyFilter.ApplyTempDataChanges(_pageContext.HttpContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
IActionResult result = null;
|
_result = await ExecuteHandlerMethod(_model);
|
||||||
|
if (_result is PageResult pageResult)
|
||||||
var handler = _selector.Select(_pageContext);
|
|
||||||
if (handler != null)
|
|
||||||
{
|
{
|
||||||
var arguments = await GetArguments(handler);
|
// If we get here, we are going to render the page, so we need to create it and then initialize
|
||||||
|
// the context so we can run the result.
|
||||||
|
_viewContext = new ViewContext(
|
||||||
|
_pageContext,
|
||||||
|
NullView.Instance,
|
||||||
|
_pageContext.ViewData,
|
||||||
|
_tempDataFactory.GetTempData(_pageContext.HttpContext),
|
||||||
|
TextWriter.Null,
|
||||||
|
_htmlHelperOptions);
|
||||||
|
|
||||||
Func<object, object[], Task<IActionResult>> executor = null;
|
_page = (Page)CacheEntry.PageFactory(_pageContext, _viewContext);
|
||||||
for (var i = 0; i < actionDescriptor.HandlerMethods.Count; i++)
|
|
||||||
|
pageResult.Page = _page;
|
||||||
|
pageResult.ViewData = pageResult.ViewData ?? _pageContext.ViewData;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _result.ExecuteResultAsync(_pageContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ExecutePageWithoutPageModelAsync()
|
||||||
|
{
|
||||||
|
// Since this is a Page without a PageModel, we need to create the Page before running a handler method.
|
||||||
|
_viewContext = new ViewContext(
|
||||||
|
_pageContext,
|
||||||
|
NullView.Instance,
|
||||||
|
_pageContext.ViewData,
|
||||||
|
_tempDataFactory.GetTempData(_pageContext.HttpContext),
|
||||||
|
TextWriter.Null,
|
||||||
|
_htmlHelperOptions);
|
||||||
|
|
||||||
|
_page = (Page)CacheEntry.PageFactory(_pageContext, _viewContext);
|
||||||
|
|
||||||
|
if (_actionDescriptor.ModelTypeInfo == _actionDescriptor.PageTypeInfo)
|
||||||
|
{
|
||||||
|
_model = _page;
|
||||||
|
_pageContext.ViewData.Model = _model;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CacheEntry.PropertyBinder != null)
|
||||||
|
{
|
||||||
|
await CacheEntry.PropertyBinder(_pageContext, _model);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a workaround for not yet having proper filter for Pages.
|
||||||
|
PageSaveTempDataPropertyFilter propertyFilter = null;
|
||||||
|
for (var i = 0; i < _filters.Length; i++)
|
||||||
|
{
|
||||||
|
propertyFilter = _filters[i] as PageSaveTempDataPropertyFilter;
|
||||||
|
if (propertyFilter != null)
|
||||||
{
|
{
|
||||||
if (object.ReferenceEquals(handler, actionDescriptor.HandlerMethods[i]))
|
break;
|
||||||
{
|
|
||||||
executor = CacheEntry.Executors[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var instance = actionDescriptor.ModelTypeInfo == actionDescriptor.HandlerTypeInfo ? _model : _page;
|
|
||||||
result = await executor(instance, arguments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null)
|
if (propertyFilter != null)
|
||||||
{
|
{
|
||||||
result = new PageResult(_page);
|
propertyFilter.Subject = _model;
|
||||||
|
propertyFilter.ApplyTempDataChanges(_pageContext.HttpContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
await result.ExecuteResultAsync(_pageContext);
|
_result = await ExecuteHandlerMethod(_model);
|
||||||
|
if (_result is PageResult pageResult)
|
||||||
|
{
|
||||||
|
// If we get here we're going to render the page so we need to initialize the context.
|
||||||
|
pageResult.Page = _page;
|
||||||
|
pageResult.ViewData = pageResult.ViewData ?? _pageContext.ViewData;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _result.ExecuteResultAsync(_pageContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<object[]> GetArguments(HandlerMethodDescriptor handler)
|
private async Task<object[]> GetArguments(HandlerMethodDescriptor handler)
|
||||||
|
|
@ -409,7 +454,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
var parameter = handler.Parameters[i];
|
var parameter = handler.Parameters[i];
|
||||||
|
|
||||||
var result = await _parameterBinder.BindModelAsync(
|
var result = await _parameterBinder.BindModelAsync(
|
||||||
_page.PageContext,
|
_pageContext,
|
||||||
valueProvider,
|
valueProvider,
|
||||||
parameter,
|
parameter,
|
||||||
value: null);
|
value: null);
|
||||||
|
|
@ -431,6 +476,36 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<IActionResult> ExecuteHandlerMethod(object instance)
|
||||||
|
{
|
||||||
|
IActionResult result = null;
|
||||||
|
|
||||||
|
var handler = _selector.Select(_pageContext);
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
var arguments = await GetArguments(handler);
|
||||||
|
|
||||||
|
Func<object, object[], Task<IActionResult>> executor = null;
|
||||||
|
for (var i = 0; i < _actionDescriptor.HandlerMethods.Count; i++)
|
||||||
|
{
|
||||||
|
if (object.ReferenceEquals(handler, _actionDescriptor.HandlerMethods[i]))
|
||||||
|
{
|
||||||
|
executor = CacheEntry.Executors[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = await executor(instance, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
result = new PageResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task InvokeNextExceptionFilterAsync()
|
private async Task InvokeNextExceptionFilterAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,10 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
|
|
@ -13,16 +16,18 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
public PageActionInvokerCacheEntry(
|
public PageActionInvokerCacheEntry(
|
||||||
CompiledPageActionDescriptor actionDescriptor,
|
CompiledPageActionDescriptor actionDescriptor,
|
||||||
Func<PageContext, object> pageFactory,
|
Func<IModelMetadataProvider, ModelStateDictionary, ViewDataDictionary> viewDataFactory,
|
||||||
Action<PageContext, object> releasePage,
|
Func<PageContext, ViewContext, object> pageFactory,
|
||||||
|
Action<PageContext, ViewContext, object> releasePage,
|
||||||
Func<PageContext, object> modelFactory,
|
Func<PageContext, object> modelFactory,
|
||||||
Action<PageContext, object> releaseModel,
|
Action<PageContext, object> releaseModel,
|
||||||
Func<Page, object, Task> propertyBinder,
|
Func<PageContext, object, Task> propertyBinder,
|
||||||
Func<object, object[], Task<IActionResult>>[] executors,
|
Func<object, object[], Task<IActionResult>>[] executors,
|
||||||
IReadOnlyList<Func<IRazorPage>> viewStartFactories,
|
IReadOnlyList<Func<IRazorPage>> viewStartFactories,
|
||||||
FilterItem[] cacheableFilters)
|
FilterItem[] cacheableFilters)
|
||||||
{
|
{
|
||||||
ActionDescriptor = actionDescriptor;
|
ActionDescriptor = actionDescriptor;
|
||||||
|
ViewDataFactory = viewDataFactory;
|
||||||
PageFactory = pageFactory;
|
PageFactory = pageFactory;
|
||||||
ReleasePage = releasePage;
|
ReleasePage = releasePage;
|
||||||
ModelFactory = modelFactory;
|
ModelFactory = modelFactory;
|
||||||
|
|
@ -35,12 +40,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
public CompiledPageActionDescriptor ActionDescriptor { get; }
|
public CompiledPageActionDescriptor ActionDescriptor { get; }
|
||||||
|
|
||||||
public Func<PageContext, object> PageFactory { get; }
|
public Func<PageContext, ViewContext, object> PageFactory { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The action invoked to release a page. This may be <c>null</c>.
|
/// The action invoked to release a page. This may be <c>null</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<PageContext, object> ReleasePage { get; }
|
public Action<PageContext, ViewContext, object> ReleasePage { get; }
|
||||||
|
|
||||||
public Func<PageContext, object> ModelFactory { get; }
|
public Func<PageContext, object> ModelFactory { get; }
|
||||||
|
|
||||||
|
|
@ -53,10 +58,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
/// The delegate invoked to bind either the handler type (page or model).
|
/// The delegate invoked to bind either the handler type (page or model).
|
||||||
/// This may be <c>null</c>.
|
/// This may be <c>null</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<Page, object, Task> PropertyBinder { get; }
|
public Func<PageContext, object, Task> PropertyBinder { get; }
|
||||||
|
|
||||||
public Func<object, object[], Task<IActionResult>>[] Executors { get; }
|
public Func<object, object[], Task<IActionResult>>[] Executors { get; }
|
||||||
|
|
||||||
|
public Func<IModelMetadataProvider, ModelStateDictionary, ViewDataDictionary> ViewDataFactory { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the applicable ViewStart pages.
|
/// Gets the applicable ViewStart pages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
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.Mvc.ViewFeatures.Internal;
|
||||||
using Microsoft.AspNetCore.Razor.Language;
|
using Microsoft.AspNetCore.Razor.Language;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.Extensions.Primitives;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
|
|
@ -146,14 +146,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
PageActionInvokerCacheEntry cacheEntry,
|
PageActionInvokerCacheEntry cacheEntry,
|
||||||
IFilterMetadata[] filters)
|
IFilterMetadata[] filters)
|
||||||
{
|
{
|
||||||
var tempData = _tempDataFactory.GetTempData(actionContext.HttpContext);
|
var pageContext = new PageContext(actionContext)
|
||||||
var pageContext = new PageContext(
|
{
|
||||||
actionContext,
|
ActionDescriptor = cacheEntry.ActionDescriptor,
|
||||||
new ViewDataDictionary(_modelMetadataProvider, actionContext.ModelState),
|
ViewData = cacheEntry.ViewDataFactory(_modelMetadataProvider, actionContext.ModelState),
|
||||||
tempData,
|
ViewStartFactories = cacheEntry.ViewStartFactories.ToList(),
|
||||||
_htmlHelperOptions);
|
};
|
||||||
|
|
||||||
pageContext.ActionDescriptor = cacheEntry.ActionDescriptor;
|
|
||||||
|
|
||||||
return new PageActionInvoker(
|
return new PageActionInvoker(
|
||||||
_selector,
|
_selector,
|
||||||
|
|
@ -163,7 +161,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
filters,
|
filters,
|
||||||
new CopyOnWriteList<IValueProviderFactory>(_valueProviderFactories),
|
new CopyOnWriteList<IValueProviderFactory>(_valueProviderFactories),
|
||||||
cacheEntry,
|
cacheEntry,
|
||||||
_parameterBinder);
|
_parameterBinder,
|
||||||
|
_tempDataFactory,
|
||||||
|
_htmlHelperOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PageActionInvokerCacheEntry CreateCacheEntry(
|
private PageActionInvokerCacheEntry CreateCacheEntry(
|
||||||
|
|
@ -173,6 +173,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
var actionDescriptor = (PageActionDescriptor)context.ActionContext.ActionDescriptor;
|
var actionDescriptor = (PageActionDescriptor)context.ActionContext.ActionDescriptor;
|
||||||
var compiledActionDescriptor = _loader.Load(actionDescriptor);
|
var compiledActionDescriptor = _loader.Load(actionDescriptor);
|
||||||
|
|
||||||
|
var viewDataFactory = ViewDataDictionaryFactory.CreateFactory(compiledActionDescriptor.ModelTypeInfo);
|
||||||
|
|
||||||
var pageFactory = _pageFactoryProvider.CreatePageFactory(compiledActionDescriptor);
|
var pageFactory = _pageFactoryProvider.CreatePageFactory(compiledActionDescriptor);
|
||||||
var pageDisposer = _pageFactoryProvider.CreatePageDisposer(compiledActionDescriptor);
|
var pageDisposer = _pageFactoryProvider.CreatePageDisposer(compiledActionDescriptor);
|
||||||
var propertyBinder = PagePropertyBinderFactory.CreateBinder(
|
var propertyBinder = PagePropertyBinderFactory.CreateBinder(
|
||||||
|
|
@ -194,6 +196,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
return new PageActionInvokerCacheEntry(
|
return new PageActionInvokerCacheEntry(
|
||||||
compiledActionDescriptor,
|
compiledActionDescriptor,
|
||||||
|
viewDataFactory,
|
||||||
pageFactory,
|
pageFactory,
|
||||||
pageDisposer,
|
pageDisposer,
|
||||||
modelFactory,
|
modelFactory,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
{
|
{
|
||||||
public static class PagePropertyBinderFactory
|
public static class PagePropertyBinderFactory
|
||||||
{
|
{
|
||||||
public static Func<Page, object, Task> CreateBinder(
|
public static Func<PageContext, object, Task> CreateBinder(
|
||||||
ParameterBinder parameterBinder,
|
ParameterBinder parameterBinder,
|
||||||
IModelMetadataProvider modelMetadataProvider,
|
IModelMetadataProvider modelMetadataProvider,
|
||||||
CompiledPageActionDescriptor actionDescriptor)
|
CompiledPageActionDescriptor actionDescriptor)
|
||||||
|
|
@ -45,20 +45,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
return Bind;
|
return Bind;
|
||||||
|
|
||||||
Task Bind(Page page, object model)
|
Task Bind(PageContext pageContext, object instance)
|
||||||
{
|
{
|
||||||
if (page == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(page));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isHandlerThePage && model == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(model));
|
|
||||||
}
|
|
||||||
|
|
||||||
var pageContext = page.PageContext;
|
|
||||||
var instance = isHandlerThePage ? page : model;
|
|
||||||
return BindPropertiesAsync(parameterBinder, pageContext, instance, properties, metadata);
|
return BindPropertiesAsync(parameterBinder, pageContext, instance, properties, metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
var razorView = (RazorView)context.View;
|
var razorView = (RazorView)context.View;
|
||||||
if (ReferenceEquals(page, razorView.RazorPage))
|
if (ReferenceEquals(page, razorView.RazorPage))
|
||||||
{
|
{
|
||||||
var pageContext = (PageContext)context;
|
var actionDescriptor = (CompiledPageActionDescriptor)context.ActionDescriptor;
|
||||||
var vddType = typeof(ViewDataDictionary<>);
|
var vddType = typeof(ViewDataDictionary<>);
|
||||||
|
|
||||||
var modelTypeInfo = pageContext.ActionDescriptor.ModelTypeInfo ?? pageContext.ActionDescriptor.PageTypeInfo;
|
var modelTypeInfo = actionDescriptor.ModelTypeInfo ?? actionDescriptor.PageTypeInfo;
|
||||||
|
|
||||||
|
|
||||||
vddType = vddType.MakeGenericType(modelTypeInfo.AsType());
|
vddType = vddType.MakeGenericType(modelTypeInfo.AsType());
|
||||||
|
|
||||||
context.ViewData = (ViewDataDictionary)Activator.CreateInstance(vddType, context.ViewData);
|
context.ViewData = (ViewDataDictionary)Activator.CreateInstance(vddType, context.ViewData);
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
public PageContext PageContext { get; set; }
|
public PageContext PageContext { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override ViewContext ViewContext
|
public override ViewContext ViewContext { get; set; }
|
||||||
{
|
|
||||||
get => PageContext;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
PageContext = (PageContext)value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="Http.HttpContext"/>.
|
/// Gets the <see cref="Http.HttpContext"/>.
|
||||||
|
|
@ -502,7 +495,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
/// Returning a <see cref="PageResult"/> from a page handler method is equivalent to returning void.
|
/// Returning a <see cref="PageResult"/> from a page handler method is equivalent to returning void.
|
||||||
/// The view associated with the page will be executed.
|
/// The view associated with the page will be executed.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public virtual PageResult Page() => new PageResult(this);
|
public virtual PageResult Page() => new PageResult();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a <see cref="RedirectResult"/> object that redirects to the specified <paramref name="url"/>.
|
/// Creates a <see cref="RedirectResult"/> object that redirects to the specified <paramref name="url"/>.
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,22 @@
|
||||||
// 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.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The context associated with the current request for a Razor page.
|
/// The context associated with the current request for a Razor page.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PageContext : ViewContext
|
public class PageContext : ActionContext
|
||||||
{
|
{
|
||||||
private CompiledPageActionDescriptor _actionDescriptor;
|
private CompiledPageActionDescriptor _actionDescriptor;
|
||||||
private Page _page;
|
|
||||||
private IList<IValueProviderFactory> _valueProviderFactories;
|
private IList<IValueProviderFactory> _valueProviderFactories;
|
||||||
|
private ViewDataDictionary _viewData;
|
||||||
|
private IList<Func<IRazorPage>> _viewStartFactories;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an empty <see cref="PageContext"/>.
|
/// Creates an empty <see cref="PageContext"/>.
|
||||||
|
|
@ -36,53 +33,32 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
/// Initializes a new instance of <see cref="PageContext"/>.
|
/// Initializes a new instance of <see cref="PageContext"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actionContext">The <see cref="ActionContext"/>.</param>
|
/// <param name="actionContext">The <see cref="ActionContext"/>.</param>
|
||||||
/// <param name="viewData">The <see cref="ViewDataDictionary"/>.</param>
|
public PageContext(ActionContext actionContext)
|
||||||
/// <param name="tempDataDictionary">The <see cref="ITempDataDictionary"/>.</param>
|
: base(actionContext)
|
||||||
/// <param name="htmlHelperOptions">The <see cref="HtmlHelperOptions"/> to apply to this instance.</param>
|
|
||||||
public PageContext(
|
|
||||||
ActionContext actionContext,
|
|
||||||
ViewDataDictionary viewData,
|
|
||||||
ITempDataDictionary tempDataDictionary,
|
|
||||||
HtmlHelperOptions htmlHelperOptions)
|
|
||||||
: base(actionContext, NullView.Instance, viewData, tempDataDictionary, TextWriter.Null, htmlHelperOptions)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the <see cref="PageActionDescriptor"/>.
|
/// Gets or sets the <see cref="PageActionDescriptor"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public new CompiledPageActionDescriptor ActionDescriptor
|
public virtual new CompiledPageActionDescriptor ActionDescriptor
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _actionDescriptor;
|
return _actionDescriptor;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
|
||||||
_actionDescriptor = value;
|
|
||||||
base.ActionDescriptor = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Page Page
|
|
||||||
{
|
|
||||||
get { return _page; }
|
|
||||||
set
|
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(value));
|
throw new ArgumentNullException(nameof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
_page = value;
|
_actionDescriptor = value;
|
||||||
|
base.ActionDescriptor = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the applicable _ViewStart instances.
|
|
||||||
/// </summary>
|
|
||||||
public IReadOnlyList<IRazorPage> ViewStarts { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the list of <see cref="IValueProviderFactory"/> instances for the current request.
|
/// Gets or sets the list of <see cref="IValueProviderFactory"/> instances for the current request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -107,5 +83,45 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
_valueProviderFactories = value;
|
_valueProviderFactories = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets <see cref="ViewDataDictionary"/>.
|
||||||
|
/// </summary>
|
||||||
|
public virtual ViewDataDictionary ViewData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _viewData;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
_viewData = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the applicable _ViewStart instances.
|
||||||
|
/// </summary>
|
||||||
|
public virtual IList<Func<IRazorPage>> ViewStartFactories
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _viewStartFactories;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
_viewStartFactories = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
using Microsoft.AspNetCore.Mvc.Routing;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
|
@ -25,48 +24,18 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
[PagesBaseClass]
|
[PagesBaseClass]
|
||||||
public abstract class PageModel
|
public abstract class PageModel
|
||||||
{
|
{
|
||||||
private IObjectModelValidator _objectValidator;
|
|
||||||
private IModelMetadataProvider _metadataProvider;
|
private IModelMetadataProvider _metadataProvider;
|
||||||
private IModelBinderFactory _modelBinderFactory;
|
private IModelBinderFactory _modelBinderFactory;
|
||||||
|
private IObjectModelValidator _objectValidator;
|
||||||
|
private ITempDataDictionary _tempData;
|
||||||
private IUrlHelper _urlHelper;
|
private IUrlHelper _urlHelper;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the <see cref="IUrlHelper"/>.
|
|
||||||
/// </summary>
|
|
||||||
public IUrlHelper Url
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_urlHelper == null)
|
|
||||||
{
|
|
||||||
var factory = HttpContext?.RequestServices?.GetRequiredService<IUrlHelperFactory>();
|
|
||||||
_urlHelper = factory?.GetUrlHelper(PageContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _urlHelper;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
_urlHelper = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="RazorPages.PageContext"/>.
|
/// Gets the <see cref="RazorPages.PageContext"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PageContext]
|
[PageContext]
|
||||||
public PageContext PageContext { get; set; }
|
public PageContext PageContext { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="ViewContext"/>.
|
|
||||||
/// </summary>
|
|
||||||
public ViewContext ViewContext => PageContext;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="Http.HttpContext"/>.
|
/// Gets the <see cref="Http.HttpContext"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -98,10 +67,61 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
public ClaimsPrincipal User => HttpContext?.User;
|
public ClaimsPrincipal User => HttpContext?.User;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="ITempDataDictionary"/> from the <see cref="PageContext"/>.
|
/// Gets or sets <see cref="ITempDataDictionary"/> used by <see cref="PageResult"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Returns null if <see cref="PageContext"/> is null.</remarks>
|
public ITempDataDictionary TempData
|
||||||
public ITempDataDictionary TempData => PageContext?.TempData;
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_tempData == null)
|
||||||
|
{
|
||||||
|
var factory = HttpContext?.RequestServices?.GetRequiredService<ITempDataDictionaryFactory>();
|
||||||
|
_tempData = factory?.GetTempData(HttpContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _tempData;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
_tempData = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the <see cref="IUrlHelper"/>.
|
||||||
|
/// </summary>
|
||||||
|
public IUrlHelper Url
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_urlHelper == null)
|
||||||
|
{
|
||||||
|
var factory = HttpContext?.RequestServices?.GetRequiredService<IUrlHelperFactory>();
|
||||||
|
_urlHelper = factory?.GetUrlHelper(PageContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _urlHelper;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
_urlHelper = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets <see cref="ViewDataDictionary"/> used by <see cref="PageResult"/>.
|
||||||
|
/// </summary>
|
||||||
|
public ViewDataDictionary ViewData => PageContext?.ViewData;
|
||||||
|
|
||||||
private IObjectModelValidator ObjectValidator
|
private IObjectModelValidator ObjectValidator
|
||||||
{
|
{
|
||||||
|
|
@ -142,11 +162,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="ViewDataDictionary"/>.
|
|
||||||
/// </summary>
|
|
||||||
public ViewDataDictionary ViewData => PageContext?.ViewData;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the specified <paramref name="model"/> instance using values from the <see cref="PageModel"/>'s current
|
/// Updates the specified <paramref name="model"/> instance using values from the <see cref="PageModel"/>'s current
|
||||||
/// <see cref="IValueProvider"/>.
|
/// <see cref="IValueProvider"/>.
|
||||||
|
|
@ -797,7 +812,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
/// Creates a <see cref="PageResult"/> object that renders the page.
|
/// Creates a <see cref="PageResult"/> object that renders the page.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The <see cref="PageResult"/>.</returns>
|
/// <returns>The <see cref="PageResult"/>.</returns>
|
||||||
public virtual PageResult Page() => new PageResult(PageContext.Page, this);
|
public virtual PageResult Page() => new PageResult();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the file specified by <paramref name="physicalPath" /> (<see cref="StatusCodes.Status200OK"/>) with the
|
/// Returns the file specified by <paramref name="physicalPath" /> (<see cref="StatusCodes.Status200OK"/>) with the
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
|
|
@ -13,26 +14,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PageResult : ActionResult
|
public class PageResult : ActionResult
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of <see cref="PageResult"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="page">The <see cref="RazorPages.PageBase"/> to render.</param>
|
|
||||||
public PageResult(PageBase page)
|
|
||||||
{
|
|
||||||
Page = page;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of <see cref="PageResult"/> with the specified <paramref name="model"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="page">The <see cref="RazorPages.PageBase"/> to render.</param>
|
|
||||||
/// <param name="model">The page model.</param>
|
|
||||||
public PageResult(PageBase page, object model)
|
|
||||||
{
|
|
||||||
Page = page;
|
|
||||||
Model = model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Content-Type header for the response.
|
/// Gets or sets the Content-Type header for the response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -41,12 +22,17 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the page model.
|
/// Gets the page model.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object Model { get; }
|
public object Model => ViewData?.Model;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="RazorPages.Page"/> to execute.
|
/// Gets or sets the <see cref="PageBase"/> to be executed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PageBase Page { get; }
|
public PageBase Page { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the <see cref="ViewDataDictionary"/> for the page to be executed.
|
||||||
|
/// </summary>
|
||||||
|
public ViewDataDictionary ViewData { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the HTTP status code.
|
/// Gets or sets the HTTP status code.
|
||||||
|
|
@ -56,14 +42,16 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task ExecuteResultAsync(ActionContext context)
|
public override Task ExecuteResultAsync(ActionContext context)
|
||||||
{
|
{
|
||||||
if (!object.ReferenceEquals(context, Page.PageContext))
|
if (!(context is PageContext pageContext))
|
||||||
{
|
{
|
||||||
throw new ArgumentException(
|
throw new ArgumentException(Resources.FormatPageViewResult_ContextIsInvalid(
|
||||||
Resources.FormatPageViewResult_ContextIsInvalid(nameof(context), nameof(Page)));
|
nameof(context),
|
||||||
|
nameof(Page),
|
||||||
|
nameof(PageResult)));
|
||||||
}
|
}
|
||||||
|
|
||||||
var executor = context.HttpContext.RequestServices.GetRequiredService<PageResultExecutor>();
|
var executor = context.HttpContext.RequestServices.GetRequiredService<PageResultExecutor>();
|
||||||
return executor.ExecuteAsync(Page.PageContext, this);
|
return executor.ExecuteAsync(pageContext, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
=> string.Format(CultureInfo.CurrentCulture, GetString("ActivatedInstance_MustBeAnInstanceOf"), p0, p1);
|
=> string.Format(CultureInfo.CurrentCulture, GetString("ActivatedInstance_MustBeAnInstanceOf"), p0, p1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Argument '{0}' is not the same instance used to create '{1}'.
|
/// The context used to execute '{0}' must be an instance of '{1}'. Returning a '{2}' from a controller is a not supported.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string PageViewResult_ContextIsInvalid
|
internal static string PageViewResult_ContextIsInvalid
|
||||||
{
|
{
|
||||||
|
|
@ -61,10 +61,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Argument '{0}' is not the same instance used to create '{1}'.
|
/// The context used to execute '{0}' must be an instance of '{1}'. Returning a '{2}' from a controller is a not supported.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string FormatPageViewResult_ContextIsInvalid(object p0, object p1)
|
internal static string FormatPageViewResult_ContextIsInvalid(object p0, object p1, object p2)
|
||||||
=> string.Format(CultureInfo.CurrentCulture, GetString("PageViewResult_ContextIsInvalid"), p0, p1);
|
=> string.Format(CultureInfo.CurrentCulture, GetString("PageViewResult_ContextIsInvalid"), p0, p1, p2);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Value cannot be null or empty.
|
/// Value cannot be null or empty.
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@
|
||||||
<value>Page created by '{0}' must be an instance of '{1}'.</value>
|
<value>Page created by '{0}' must be an instance of '{1}'.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PageViewResult_ContextIsInvalid" xml:space="preserve">
|
<data name="PageViewResult_ContextIsInvalid" xml:space="preserve">
|
||||||
<value>Argument '{0}' is not the same instance used to create '{1}'.</value>
|
<value>The context used to execute '{0}' must be an instance of '{1}'. Returning a '{2}' from a controller is a not supported.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
|
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
|
||||||
<value>Value cannot be null or empty.</value>
|
<value>Value cannot be null or empty.</value>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
|
||||||
|
{
|
||||||
|
public static class ViewDataDictionaryFactory
|
||||||
|
{
|
||||||
|
public static Func<IModelMetadataProvider, ModelStateDictionary, ViewDataDictionary> CreateFactory(TypeInfo modelType)
|
||||||
|
{
|
||||||
|
if (modelType == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(modelType));
|
||||||
|
}
|
||||||
|
|
||||||
|
var type = typeof(ViewDataDictionary<>).MakeGenericType(modelType);
|
||||||
|
var constructor = type.GetConstructor(new Type[] { typeof(IModelMetadataProvider), typeof(ModelStateDictionary) });
|
||||||
|
Debug.Assert(constructor != null);
|
||||||
|
|
||||||
|
var parameter1 = Expression.Parameter(typeof(IModelMetadataProvider), "metadataProvider");
|
||||||
|
var parameter2 = Expression.Parameter(typeof(ModelStateDictionary), "modelState");
|
||||||
|
|
||||||
|
return
|
||||||
|
Expression.Lambda<Func<IModelMetadataProvider, ModelStateDictionary, ViewDataDictionary>>(
|
||||||
|
Expression.Convert(
|
||||||
|
Expression.New(constructor, parameter1, parameter2),
|
||||||
|
typeof(ViewDataDictionary)),
|
||||||
|
parameter1,
|
||||||
|
parameter2)
|
||||||
|
.Compile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Func<ViewDataDictionary, ViewDataDictionary> CreateNestedFactory(TypeInfo modelType)
|
||||||
|
{
|
||||||
|
if (modelType == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(modelType));
|
||||||
|
}
|
||||||
|
|
||||||
|
var type = typeof(ViewDataDictionary<>).MakeGenericType(modelType);
|
||||||
|
var constructor = type.GetConstructor(new Type[] { typeof(ViewDataDictionary) });
|
||||||
|
Debug.Assert(constructor != null);
|
||||||
|
|
||||||
|
var parameter = Expression.Parameter(typeof(ViewDataDictionary), "viewDataDictionary");
|
||||||
|
|
||||||
|
return
|
||||||
|
Expression.Lambda<Func<ViewDataDictionary, ViewDataDictionary>>(
|
||||||
|
Expression.Convert(
|
||||||
|
Expression.New(constructor, parameter),
|
||||||
|
typeof(ViewDataDictionary)),
|
||||||
|
parameter)
|
||||||
|
.Compile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,20 +4,21 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
public class DefaultPageActivatorTest
|
public class DefaultPageActivatorProviderTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void CreateActivator_ThrowsIfPageTypeInfoIsNull()
|
public void CreateActivator_ThrowsIfPageTypeInfoIsNull()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var descriptor = new CompiledPageActionDescriptor();
|
var descriptor = new CompiledPageActionDescriptor();
|
||||||
var activator = new DefaultPageActivator();
|
var activator = new DefaultPageActivatorProvider();
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
ExceptionAssert.ThrowsArgument(
|
ExceptionAssert.ThrowsArgument(
|
||||||
|
|
@ -33,16 +34,18 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var pageContext = new PageContext();
|
var pageContext = new PageContext();
|
||||||
|
var viewContext = new ViewContext();
|
||||||
var descriptor = new CompiledPageActionDescriptor
|
var descriptor = new CompiledPageActionDescriptor
|
||||||
{
|
{
|
||||||
PageTypeInfo = type.GetTypeInfo(),
|
PageTypeInfo = type.GetTypeInfo(),
|
||||||
};
|
};
|
||||||
|
|
||||||
var activator = new DefaultPageActivator();
|
|
||||||
|
var activator = new DefaultPageActivatorProvider();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var factory = activator.CreateActivator(descriptor);
|
var factory = activator.CreateActivator(descriptor);
|
||||||
var instance = factory(pageContext);
|
var instance = factory(pageContext, viewContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(instance);
|
Assert.NotNull(instance);
|
||||||
|
|
@ -58,7 +61,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
PageTypeInfo = typeof(PageWithoutParameterlessConstructor).GetTypeInfo(),
|
PageTypeInfo = typeof(PageWithoutParameterlessConstructor).GetTypeInfo(),
|
||||||
};
|
};
|
||||||
var pageContext = new PageContext();
|
var pageContext = new PageContext();
|
||||||
var activator = new DefaultPageActivator();
|
var activator = new DefaultPageActivatorProvider();
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.Throws<ArgumentException>(() => activator.CreateActivator(descriptor));
|
Assert.Throws<ArgumentException>(() => activator.CreateActivator(descriptor));
|
||||||
|
|
@ -71,7 +74,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var context = new PageContext();
|
var context = new PageContext();
|
||||||
var activator = new DefaultPageActivator();
|
var activator = new DefaultPageActivatorProvider();
|
||||||
var page = new TestPage();
|
var page = new TestPage();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -89,7 +92,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var context = new PageContext();
|
var context = new PageContext();
|
||||||
var activator = new DefaultPageActivator();
|
var viewContext = new ViewContext();
|
||||||
|
var activator = new DefaultPageActivatorProvider();
|
||||||
var page = new DisposablePage();
|
var page = new DisposablePage();
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
|
|
@ -98,7 +102,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
PageTypeInfo = page.GetType().GetTypeInfo()
|
PageTypeInfo = page.GetType().GetTypeInfo()
|
||||||
});
|
});
|
||||||
Assert.NotNull(disposer);
|
Assert.NotNull(disposer);
|
||||||
disposer(context, page);
|
disposer(context, viewContext, page);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(page.Disposed);
|
Assert.True(page.Disposed);
|
||||||
|
|
@ -53,11 +53,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
ActionDescriptor = descriptor
|
ActionDescriptor = descriptor
|
||||||
};
|
};
|
||||||
|
var viewContext = new ViewContext();
|
||||||
var factoryProvider = CreatePageFactory();
|
var factoryProvider = CreatePageFactory();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var factory = factoryProvider.CreatePageFactory(descriptor);
|
var factory = factoryProvider.CreatePageFactory(descriptor);
|
||||||
var instance = factory(pageContext);
|
var instance = factory(pageContext, viewContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var testPage = Assert.IsType<TestPage>(instance);
|
var testPage = Assert.IsType<TestPage>(instance);
|
||||||
|
|
@ -75,11 +76,16 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
PageTypeInfo = typeof(TestPage).GetTypeInfo(),
|
PageTypeInfo = typeof(TestPage).GetTypeInfo(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var viewContext = new ViewContext();
|
||||||
|
|
||||||
var urlHelperFactory = new Mock<IUrlHelperFactory>();
|
var urlHelperFactory = new Mock<IUrlHelperFactory>();
|
||||||
var urlHelper = Mock.Of<IUrlHelper>();
|
var urlHelper = Mock.Of<IUrlHelper>();
|
||||||
urlHelperFactory.Setup(f => f.GetUrlHelper(pageContext))
|
urlHelperFactory
|
||||||
|
.Setup(f => f.GetUrlHelper(viewContext))
|
||||||
.Returns(urlHelper)
|
.Returns(urlHelper)
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
|
|
||||||
var htmlEncoder = HtmlEncoder.Create();
|
var htmlEncoder = HtmlEncoder.Create();
|
||||||
|
|
||||||
var factoryProvider = CreatePageFactory(
|
var factoryProvider = CreatePageFactory(
|
||||||
|
|
@ -88,7 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
||||||
var instance = factory(pageContext);
|
var instance = factory(pageContext, viewContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var testPage = Assert.IsType<TestPage>(instance);
|
var testPage = Assert.IsType<TestPage>(instance);
|
||||||
|
|
@ -113,9 +119,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
ActionDescriptor = descriptor
|
ActionDescriptor = descriptor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var viewContext = new ViewContext();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var factory = CreatePageFactory().CreatePageFactory(descriptor);
|
var factory = CreatePageFactory().CreatePageFactory(descriptor);
|
||||||
var instance = factory(pageContext);
|
var instance = factory(pageContext, viewContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var testPage = Assert.IsType<ViewDataTestPage>(instance);
|
var testPage = Assert.IsType<ViewDataTestPage>(instance);
|
||||||
|
|
@ -135,11 +143,13 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var viewContext = new ViewContext();
|
||||||
|
|
||||||
var factoryProvider = CreatePageFactory();
|
var factoryProvider = CreatePageFactory();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
||||||
var instance = factory(pageContext);
|
var instance = factory(pageContext, viewContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var testPage = Assert.IsType<ViewDataTestPage>(instance);
|
var testPage = Assert.IsType<ViewDataTestPage>(instance);
|
||||||
|
|
@ -158,11 +168,13 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var viewContext = new ViewContext();
|
||||||
|
|
||||||
var factoryProvider = CreatePageFactory();
|
var factoryProvider = CreatePageFactory();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
||||||
var instance = factory(pageContext);
|
var instance = factory(pageContext, viewContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var testPage = Assert.IsType<NonGenericViewDataTestPage>(instance);
|
var testPage = Assert.IsType<NonGenericViewDataTestPage>(instance);
|
||||||
|
|
@ -170,7 +182,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void PageFactorySetsNestedVidewDataDictionaryWhenContextHasANonNullDictionary()
|
public void PageFactory_SetsViewDataOnPage_FromPageContext()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var modelMetadataProvider = new EmptyModelMetadataProvider();
|
var modelMetadataProvider = new EmptyModelMetadataProvider();
|
||||||
|
|
@ -180,21 +192,28 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
PageTypeInfo = typeof(TestPage).GetTypeInfo()
|
PageTypeInfo = typeof(TestPage).GetTypeInfo()
|
||||||
},
|
},
|
||||||
ViewData = new ViewDataDictionary(modelMetadataProvider, new ModelStateDictionary())
|
ViewData = new ViewDataDictionary<TestPage>(modelMetadataProvider, new ModelStateDictionary())
|
||||||
{
|
{
|
||||||
{ "test-key", "test-value" },
|
{ "test-key", "test-value" },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var viewContext = new ViewContext()
|
||||||
|
{
|
||||||
|
HttpContext = pageContext.HttpContext,
|
||||||
|
ViewData = pageContext.ViewData,
|
||||||
|
};
|
||||||
|
|
||||||
var factoryProvider = CreatePageFactory();
|
var factoryProvider = CreatePageFactory();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
||||||
var instance = factory(pageContext);
|
var instance = factory(pageContext, viewContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var testPage = Assert.IsType<TestPage>(instance);
|
var testPage = Assert.IsType<TestPage>(instance);
|
||||||
Assert.NotNull(testPage.ViewData);
|
Assert.NotNull(testPage.ViewData);
|
||||||
|
Assert.Same(pageContext.ViewData, testPage.ViewData);
|
||||||
Assert.Equal("test-value", testPage.ViewData["test-key"]);
|
Assert.Equal("test-value", testPage.ViewData["test-key"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,6 +224,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
var serviceProvider = new ServiceCollection()
|
var serviceProvider = new ServiceCollection()
|
||||||
.AddSingleton<ILogger>(NullLogger.Instance)
|
.AddSingleton<ILogger>(NullLogger.Instance)
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
|
|
||||||
var pageContext = new PageContext
|
var pageContext = new PageContext
|
||||||
{
|
{
|
||||||
ActionDescriptor = new CompiledPageActionDescriptor
|
ActionDescriptor = new CompiledPageActionDescriptor
|
||||||
|
|
@ -215,14 +235,18 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
RequestServices = serviceProvider,
|
RequestServices = serviceProvider,
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var viewContext = new ViewContext()
|
||||||
|
{
|
||||||
|
HttpContext = pageContext.HttpContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
var factoryProvider = CreatePageFactory();
|
var factoryProvider = CreatePageFactory();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
var factory = factoryProvider.CreatePageFactory(pageContext.ActionDescriptor);
|
||||||
var instance = factory(pageContext);
|
var instance = factory(pageContext, viewContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var testPage = Assert.IsType<PropertiesWithoutRazorInject>(instance);
|
var testPage = Assert.IsType<PropertiesWithoutRazorInject>(instance);
|
||||||
|
|
@ -258,10 +282,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
private static IPageActivatorProvider CreateActivator()
|
private static IPageActivatorProvider CreateActivator()
|
||||||
{
|
{
|
||||||
var activator = new Mock<IPageActivatorProvider>();
|
var activator = new Mock<IPageActivatorProvider>();
|
||||||
activator.Setup(a => a.CreateActivator(It.IsAny<CompiledPageActionDescriptor>()))
|
activator
|
||||||
|
.Setup(a => a.CreateActivator(It.IsAny<CompiledPageActionDescriptor>()))
|
||||||
.Returns((CompiledPageActionDescriptor descriptor) =>
|
.Returns((CompiledPageActionDescriptor descriptor) =>
|
||||||
{
|
{
|
||||||
return (context) => Activator.CreateInstance(descriptor.PageTypeInfo.AsType());
|
return (context, viewContext) => Activator.CreateInstance(descriptor.PageTypeInfo.AsType());
|
||||||
});
|
});
|
||||||
return activator.Object;
|
return activator.Object;
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
@ -95,7 +96,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var context = new PageContext();
|
var context = new PageContext();
|
||||||
var activator = new DefaultPageActivator();
|
var activator = new DefaultPageModelActivatorProvider();
|
||||||
var actionDescriptor = new CompiledPageActionDescriptor
|
var actionDescriptor = new CompiledPageActionDescriptor
|
||||||
{
|
{
|
||||||
PageTypeInfo = pageType.GetTypeInfo(),
|
PageTypeInfo = pageType.GetTypeInfo(),
|
||||||
|
|
@ -113,11 +114,13 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var context = new PageContext();
|
var context = new PageContext();
|
||||||
var activator = new DefaultPageActivator();
|
|
||||||
|
var activator = new DefaultPageModelActivatorProvider();
|
||||||
var actionDescriptor = new CompiledPageActionDescriptor
|
var actionDescriptor = new CompiledPageActionDescriptor
|
||||||
{
|
{
|
||||||
PageTypeInfo = typeof(DisposableModel).GetTypeInfo(),
|
ModelTypeInfo = typeof(DisposableModel).GetTypeInfo(),
|
||||||
};
|
};
|
||||||
|
|
||||||
var model = new DisposableModel();
|
var model = new DisposableModel();
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
|
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;
|
||||||
using Microsoft.AspNetCore.Razor.Language;
|
using Microsoft.AspNetCore.Razor.Language;
|
||||||
|
|
@ -38,8 +39,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
FilterDescriptors = new FilterDescriptor[0],
|
FilterDescriptors = new FilterDescriptor[0],
|
||||||
};
|
};
|
||||||
|
|
||||||
Func<PageContext, object> factory = _ => null;
|
Func<PageContext, ViewContext, object> factory = (a, b) => null;
|
||||||
Action<PageContext, object> releaser = (_, __) => { };
|
Action<PageContext, ViewContext, object> releaser = (a, b, c) => { };
|
||||||
|
|
||||||
var loader = new Mock<IPageLoader>();
|
var loader = new Mock<IPageLoader>();
|
||||||
loader
|
loader
|
||||||
|
|
@ -78,6 +79,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
Assert.Same(releaser, entry.ReleasePage);
|
Assert.Same(releaser, entry.ReleasePage);
|
||||||
Assert.Null(entry.ModelFactory);
|
Assert.Null(entry.ModelFactory);
|
||||||
Assert.Null(entry.ReleaseModel);
|
Assert.Null(entry.ReleaseModel);
|
||||||
|
Assert.NotNull(entry.ViewDataFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -90,8 +92,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
FilterDescriptors = new FilterDescriptor[0],
|
FilterDescriptors = new FilterDescriptor[0],
|
||||||
};
|
};
|
||||||
|
|
||||||
Func<PageContext, object> factory = _ => null;
|
Func<PageContext, ViewContext, object> factory = (a, b) => null;
|
||||||
Action<PageContext, object> releaser = (_, __) => { };
|
Action<PageContext, ViewContext, object> releaser = (a, b, c) => { };
|
||||||
Func<PageContext, object> modelFactory = _ => null;
|
Func<PageContext, object> modelFactory = _ => null;
|
||||||
Action<PageContext, object> modelDisposer = (_, __) => { };
|
Action<PageContext, object> modelDisposer = (_, __) => { };
|
||||||
|
|
||||||
|
|
@ -134,7 +136,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(context.Result);
|
Assert.NotNull(context.Result);
|
||||||
|
|
||||||
var actionInvoker = Assert.IsType<PageActionInvoker>(context.Result);
|
var actionInvoker = Assert.IsType<PageActionInvoker>(context.Result);
|
||||||
|
|
||||||
var entry = actionInvoker.CacheEntry;
|
var entry = actionInvoker.CacheEntry;
|
||||||
var compiledPageActionDescriptor = Assert.IsType<CompiledPageActionDescriptor>(entry.ActionDescriptor);
|
var compiledPageActionDescriptor = Assert.IsType<CompiledPageActionDescriptor>(entry.ActionDescriptor);
|
||||||
Assert.Equal(descriptor.RelativePath, compiledPageActionDescriptor.RelativePath);
|
Assert.Equal(descriptor.RelativePath, compiledPageActionDescriptor.RelativePath);
|
||||||
|
|
@ -142,6 +146,16 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
Assert.Same(releaser, entry.ReleasePage);
|
Assert.Same(releaser, entry.ReleasePage);
|
||||||
Assert.Same(modelFactory, entry.ModelFactory);
|
Assert.Same(modelFactory, entry.ModelFactory);
|
||||||
Assert.Same(modelDisposer, entry.ReleaseModel);
|
Assert.Same(modelDisposer, entry.ReleaseModel);
|
||||||
|
Assert.NotNull(entry.ViewDataFactory);
|
||||||
|
|
||||||
|
var pageContext = actionInvoker.PageContext;
|
||||||
|
Assert.Same(compiledPageActionDescriptor, pageContext.ActionDescriptor);
|
||||||
|
Assert.Same(context.ActionContext.HttpContext, pageContext.HttpContext);
|
||||||
|
Assert.Same(context.ActionContext.ModelState, pageContext.ModelState);
|
||||||
|
Assert.Same(context.ActionContext.RouteData, pageContext.RouteData);
|
||||||
|
Assert.Empty(pageContext.ValueProviderFactories);
|
||||||
|
Assert.NotNull(Assert.IsType<ViewDataDictionary<TestPageModel>>(pageContext.ViewData));
|
||||||
|
Assert.Empty(pageContext.ViewStartFactories);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -476,16 +490,20 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
PageActionDescriptor descriptor,
|
PageActionDescriptor descriptor,
|
||||||
Type pageType = null)
|
Type pageType = null)
|
||||||
{
|
{
|
||||||
|
pageType = pageType ?? typeof(object);
|
||||||
|
var pageTypeInfo = pageType.GetTypeInfo();
|
||||||
|
|
||||||
TypeInfo modelTypeInfo = null;
|
TypeInfo modelTypeInfo = null;
|
||||||
if (pageType != null)
|
if (pageType != null)
|
||||||
{
|
{
|
||||||
modelTypeInfo = pageType.GetTypeInfo().GetProperty("Model")?.PropertyType.GetTypeInfo();
|
modelTypeInfo = pageTypeInfo.GetProperty("Model")?.PropertyType.GetTypeInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CompiledPageActionDescriptor(descriptor)
|
return new CompiledPageActionDescriptor(descriptor)
|
||||||
{
|
{
|
||||||
ModelTypeInfo = modelTypeInfo,
|
HandlerTypeInfo = modelTypeInfo ?? pageTypeInfo,
|
||||||
PageTypeInfo = (pageType ?? typeof(object)).GetTypeInfo()
|
ModelTypeInfo = modelTypeInfo ?? pageTypeInfo,
|
||||||
|
PageTypeInfo = pageTypeInfo,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,10 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
@ -344,10 +346,18 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
|
|
||||||
var filter3 = new Mock<IAuthorizationFilter>(MockBehavior.Strict);
|
var filter3 = new Mock<IAuthorizationFilter>(MockBehavior.Strict);
|
||||||
var actionDescriptor = new CompiledPageActionDescriptor();
|
|
||||||
|
var actionDescriptor = new CompiledPageActionDescriptor()
|
||||||
|
{
|
||||||
|
HandlerTypeInfo = typeof(TestPage).GetTypeInfo(),
|
||||||
|
ModelTypeInfo = typeof(TestPage).GetTypeInfo(),
|
||||||
|
PageTypeInfo = typeof(TestPage).GetTypeInfo(),
|
||||||
|
};
|
||||||
|
|
||||||
var cacheEntry = new PageActionInvokerCacheEntry(
|
var cacheEntry = new PageActionInvokerCacheEntry(
|
||||||
actionDescriptor,
|
actionDescriptor,
|
||||||
(context) => createCalled = true,
|
null,
|
||||||
|
(context, viewContext) => createCalled = true,
|
||||||
null,
|
null,
|
||||||
(context) => null,
|
(context) => null,
|
||||||
null,
|
null,
|
||||||
|
|
@ -400,10 +410,17 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
var filter3 = new Mock<IAuthorizationFilter>(MockBehavior.Strict);
|
var filter3 = new Mock<IAuthorizationFilter>(MockBehavior.Strict);
|
||||||
|
|
||||||
var actionDescriptor = new CompiledPageActionDescriptor();
|
var actionDescriptor = new CompiledPageActionDescriptor()
|
||||||
|
{
|
||||||
|
HandlerTypeInfo = typeof(TestPage).GetTypeInfo(),
|
||||||
|
ModelTypeInfo = typeof(TestPage).GetTypeInfo(),
|
||||||
|
PageTypeInfo = typeof(TestPage).GetTypeInfo(),
|
||||||
|
};
|
||||||
|
|
||||||
var cacheEntry = new PageActionInvokerCacheEntry(
|
var cacheEntry = new PageActionInvokerCacheEntry(
|
||||||
actionDescriptor,
|
actionDescriptor,
|
||||||
(context) => createCalled = true,
|
null,
|
||||||
|
(context, viewContext) => createCalled = true,
|
||||||
null,
|
null,
|
||||||
(context) => null,
|
(context) => null,
|
||||||
null,
|
null,
|
||||||
|
|
@ -540,6 +557,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
PageResultExecutor executor = null,
|
PageResultExecutor executor = null,
|
||||||
IPageHandlerMethodSelector selector = null,
|
IPageHandlerMethodSelector selector = null,
|
||||||
PageActionInvokerCacheEntry cacheEntry = null,
|
PageActionInvokerCacheEntry cacheEntry = null,
|
||||||
|
ITempDataDictionaryFactory tempDataFactory = null,
|
||||||
int maxAllowedErrorsInModelState = 200,
|
int maxAllowedErrorsInModelState = 200,
|
||||||
List<IValueProviderFactory> valueProviderFactories = null,
|
List<IValueProviderFactory> valueProviderFactories = null,
|
||||||
RouteData routeData = null,
|
RouteData routeData = null,
|
||||||
|
|
@ -572,15 +590,14 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
httpContext: httpContext,
|
httpContext: httpContext,
|
||||||
routeData: routeData,
|
routeData: routeData,
|
||||||
actionDescriptor: actionDescriptor);
|
actionDescriptor: actionDescriptor);
|
||||||
var pageContext = new PageContext(
|
var pageContext = new PageContext(actionContext)
|
||||||
actionContext,
|
|
||||||
new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()),
|
|
||||||
Mock.Of<ITempDataDictionary>(),
|
|
||||||
new HtmlHelperOptions())
|
|
||||||
{
|
{
|
||||||
ActionDescriptor = actionDescriptor
|
ActionDescriptor = actionDescriptor,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var viewDataFactory = ViewDataDictionaryFactory.CreateFactory(actionDescriptor.ModelTypeInfo);
|
||||||
|
pageContext.ViewData = viewDataFactory(new EmptyModelMetadataProvider(), pageContext.ModelState);
|
||||||
|
|
||||||
if (selector == null)
|
if (selector == null)
|
||||||
{
|
{
|
||||||
selector = Mock.Of<IPageHandlerMethodSelector>();
|
selector = Mock.Of<IPageHandlerMethodSelector>();
|
||||||
|
|
@ -596,7 +613,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
logger = NullLogger.Instance;
|
logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Func<PageContext, object> pageFactory = (context) =>
|
if (tempDataFactory == null)
|
||||||
|
{
|
||||||
|
tempDataFactory = Mock.Of<ITempDataDictionaryFactory>(m => m.GetTempData(It.IsAny<HttpContext>()) == Mock.Of<ITempDataDictionary>());
|
||||||
|
}
|
||||||
|
|
||||||
|
Func<PageContext, ViewContext, object> pageFactory = (context, viewContext) =>
|
||||||
{
|
{
|
||||||
var instance = (Page)Activator.CreateInstance(actionDescriptor.PageTypeInfo.AsType());
|
var instance = (Page)Activator.CreateInstance(actionDescriptor.PageTypeInfo.AsType());
|
||||||
instance.PageContext = context;
|
instance.PageContext = context;
|
||||||
|
|
@ -605,8 +627,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
|
||||||
cacheEntry = new PageActionInvokerCacheEntry(
|
cacheEntry = new PageActionInvokerCacheEntry(
|
||||||
actionDescriptor,
|
actionDescriptor,
|
||||||
|
viewDataFactory,
|
||||||
pageFactory,
|
pageFactory,
|
||||||
(c, page) => { (page as IDisposable)?.Dispose(); },
|
(c, viewContext, 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,
|
null,
|
||||||
|
|
@ -622,7 +645,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
filters,
|
filters,
|
||||||
valueProviderFactories.AsReadOnly(),
|
valueProviderFactories.AsReadOnly(),
|
||||||
cacheEntry,
|
cacheEntry,
|
||||||
GetParameterBinder());
|
GetParameterBinder(),
|
||||||
|
tempDataFactory,
|
||||||
|
new HtmlHelperOptions());
|
||||||
return invoker;
|
return invoker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await factory(page, null);
|
await factory(page.PageContext, page);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(10, page.Id);
|
Assert.Equal(10, page.Id);
|
||||||
|
|
@ -262,7 +262,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
var model = new PageModelWithProperty();
|
var model = new PageModelWithProperty();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await factory(page, model);
|
await factory(page.PageContext, model);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
// Verify that the page properties were not bound.
|
// Verify that the page properties were not bound.
|
||||||
|
|
@ -314,7 +314,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
var defaultValue = model.PropertyWithDefaultValue;
|
var defaultValue = model.PropertyWithDefaultValue;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await factory(page, model);
|
await factory(page.PageContext, model);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(defaultValue, model.PropertyWithDefaultValue);
|
Assert.Equal(defaultValue, model.PropertyWithDefaultValue);
|
||||||
|
|
@ -375,7 +375,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
var model = new PageModelWithSupportsGetProperty();
|
var model = new PageModelWithSupportsGetProperty();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await factory(page, model);
|
await factory(page.PageContext, model);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("value", model.SupportsGet);
|
Assert.Equal("value", model.SupportsGet);
|
||||||
|
|
@ -434,7 +434,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
var model = new PageModelWithSupportsGetProperty();
|
var model = new PageModelWithSupportsGetProperty();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await factory(page, model);
|
await factory(page.PageContext, model);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("value", model.SupportsGet);
|
Assert.Equal("value", model.SupportsGet);
|
||||||
|
|
|
||||||
|
|
@ -1406,15 +1406,16 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
var modelState = new ModelStateDictionary();
|
var modelState = new ModelStateDictionary();
|
||||||
var actionContext = new ActionContext(httpContext, new RouteData(), new PageActionDescriptor(), modelState);
|
var actionContext = new ActionContext(httpContext, new RouteData(), new PageActionDescriptor(), modelState);
|
||||||
var modelMetadataProvider = new EmptyModelMetadataProvider();
|
var modelMetadataProvider = new EmptyModelMetadataProvider();
|
||||||
var viewDataDictionary = new ViewDataDictionary(modelMetadataProvider, modelState);
|
var viewData = new ViewDataDictionary(modelMetadataProvider, modelState);
|
||||||
var tempData = Mock.Of<ITempDataDictionary>();
|
var pageContext = new PageContext(actionContext)
|
||||||
var pageContext = new PageContext(actionContext, viewDataDictionary, tempData, new HtmlHelperOptions());
|
{
|
||||||
|
ViewData = viewData,
|
||||||
|
};
|
||||||
|
|
||||||
var page = new TestPage
|
var page = new TestPage
|
||||||
{
|
{
|
||||||
PageContext = pageContext,
|
PageContext = pageContext,
|
||||||
};
|
};
|
||||||
pageContext.Page = page;
|
|
||||||
|
|
||||||
var pageModel = new TestPageModel
|
var pageModel = new TestPageModel
|
||||||
{
|
{
|
||||||
|
|
@ -1423,13 +1424,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.Same(pageContext, pageModel.PageContext);
|
Assert.Same(pageContext, pageModel.PageContext);
|
||||||
Assert.Same(pageContext, pageModel.ViewContext);
|
|
||||||
Assert.Same(httpContext, pageModel.HttpContext);
|
Assert.Same(httpContext, pageModel.HttpContext);
|
||||||
Assert.Same(httpContext.Request, pageModel.Request);
|
Assert.Same(httpContext.Request, pageModel.Request);
|
||||||
Assert.Same(httpContext.Response, pageModel.Response);
|
Assert.Same(httpContext.Response, pageModel.Response);
|
||||||
Assert.Same(modelState, pageModel.ModelState);
|
Assert.Same(modelState, pageModel.ModelState);
|
||||||
Assert.Same(viewDataDictionary, pageModel.ViewData);
|
Assert.Same(viewData, pageModel.ViewData);
|
||||||
Assert.Same(tempData, pageModel.TempData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -1483,10 +1482,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
var page = new TestPage();
|
var page = new TestPage();
|
||||||
var pageModel = new TestPageModel
|
var pageModel = new TestPageModel
|
||||||
{
|
{
|
||||||
PageContext = new PageContext
|
PageContext = new PageContext()
|
||||||
{
|
|
||||||
Page = page,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -1494,7 +1490,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var pageResult = Assert.IsType<PageResult>(result);
|
var pageResult = Assert.IsType<PageResult>(result);
|
||||||
Assert.Same(page, pageResult.Page);
|
Assert.Null(pageResult.Page); // This is set by the invoker
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ContentPageModel : PageModel
|
private class ContentPageModel : PageModel
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,10 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Formatters;
|
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.AspNetCore.Mvc.TestCommon;
|
using Microsoft.AspNetCore.Mvc.TestCommon;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
|
@ -28,17 +30,24 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
|
||||||
var modelState = new ModelStateDictionary();
|
var modelState = new ModelStateDictionary();
|
||||||
var actionContext = new ActionContext(httpContext, new RouteData(), new PageActionDescriptor(), modelState);
|
var actionContext = new ActionContext(httpContext, new RouteData(), new PageActionDescriptor(), modelState);
|
||||||
var modelMetadataProvider = new EmptyModelMetadataProvider();
|
var modelMetadataProvider = new EmptyModelMetadataProvider();
|
||||||
var viewDataDictionary = new ViewDataDictionary(modelMetadataProvider, modelState);
|
var viewData = new ViewDataDictionary(modelMetadataProvider, modelState);
|
||||||
var tempData = Mock.Of<ITempDataDictionary>();
|
var tempData = Mock.Of<ITempDataDictionary>();
|
||||||
var pageContext = new PageContext(actionContext, viewDataDictionary, tempData, new HtmlHelperOptions());
|
|
||||||
|
var pageContext = new PageContext(actionContext)
|
||||||
|
{
|
||||||
|
ViewData = viewData,
|
||||||
|
};
|
||||||
|
var viewContext = new ViewContext(pageContext, NullView.Instance, viewData, tempData, TextWriter.Null, new HtmlHelperOptions());
|
||||||
|
|
||||||
var page = new TestPage
|
var page = new TestPage
|
||||||
{
|
{
|
||||||
PageContext = pageContext,
|
PageContext = pageContext,
|
||||||
|
ViewContext = viewContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.Same(pageContext, page.ViewContext);
|
Assert.Same(pageContext, page.PageContext);
|
||||||
|
Assert.Same(viewContext, page.ViewContext);
|
||||||
Assert.Same(httpContext, page.HttpContext);
|
Assert.Same(httpContext, page.HttpContext);
|
||||||
Assert.Same(httpContext.Request, page.Request);
|
Assert.Same(httpContext.Request, page.Request);
|
||||||
Assert.Same(httpContext.Response, page.Response);
|
Assert.Same(httpContext.Response, page.Response);
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -164,7 +166,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
|
||||||
var testProp = pageType.GetProperty(nameof(TestPageString.Test));
|
var testProp = pageType.GetProperty(nameof(TestPageString.Test));
|
||||||
var test2Prop = pageType.GetProperty(nameof(TestPageString.Test2));
|
var test2Prop = pageType.GetProperty(nameof(TestPageString.Test2));
|
||||||
|
|
||||||
provider.TempDataProperties = new List<TempDataProperty> {
|
provider.TempDataProperties = new List<TempDataProperty>
|
||||||
|
{
|
||||||
new TempDataProperty(testProp, testProp.GetValue, testProp.SetValue),
|
new TempDataProperty(testProp, testProp.GetValue, testProp.SetValue),
|
||||||
new TempDataProperty(test2Prop, test2Prop.GetValue, test2Prop.SetValue)
|
new TempDataProperty(test2Prop, test2Prop.GetValue, test2Prop.SetValue)
|
||||||
};
|
};
|
||||||
|
|
@ -177,15 +180,17 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
|
||||||
Assert.Null(page.Test2);
|
Assert.Null(page.Test2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PageContext CreateViewContext(HttpContext httpContext, ITempDataDictionary tempData)
|
private static ViewContext CreateViewContext(HttpContext httpContext, ITempDataDictionary tempData)
|
||||||
{
|
{
|
||||||
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||||
var metadataProvider = new EmptyModelMetadataProvider();
|
var metadataProvider = new EmptyModelMetadataProvider();
|
||||||
var viewData = new ViewDataDictionary(metadataProvider, new ModelStateDictionary());
|
var viewData = new ViewDataDictionary(metadataProvider, new ModelStateDictionary());
|
||||||
var viewContext = new PageContext(
|
var viewContext = new ViewContext(
|
||||||
actionContext,
|
actionContext,
|
||||||
|
NullView.Instance,
|
||||||
viewData,
|
viewData,
|
||||||
tempData,
|
tempData,
|
||||||
|
TextWriter.Null,
|
||||||
new HtmlHelperOptions());
|
new HtmlHelperOptions());
|
||||||
|
|
||||||
return viewContext;
|
return viewContext;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue