diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageActivator.cs b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageActivator.cs
index 5ed5746211..4000df8184 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageActivator.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageActivator.cs
@@ -3,7 +3,9 @@
using System;
using System.Collections.Concurrent;
+using System.Diagnostics;
using System.Reflection;
+using System.Linq.Expressions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.AspNetCore.Mvc.Rendering;
@@ -17,6 +19,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor
///
public class RazorPageActivator : IRazorPageActivator
{
+ private delegate ViewDataDictionary CreateViewDataNested(ViewDataDictionary source);
+ private delegate ViewDataDictionary CreateViewDataRoot(
+ IModelMetadataProvider metadataProvider,
+ ModelStateDictionary modelState);
+
// Name of the "public TModel Model" property on RazorPage
private const string ModelPropertyName = "Model";
private readonly ConcurrentDictionary _activationInfo;
@@ -63,17 +70,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor
if (context.ViewData == null)
{
// Create ViewDataDictionary(IModelMetadataProvider, ModelStateDictionary).
- return (ViewDataDictionary)Activator.CreateInstance(
- activationInfo.ViewDataDictionaryType,
+ return activationInfo.CreateViewDataRoot(
_metadataProvider,
context.ModelState);
}
else if (context.ViewData.GetType() != activationInfo.ViewDataDictionaryType)
{
// Create ViewDataDictionary(ViewDataDictionary).
- return (ViewDataDictionary)Activator.CreateInstance(
- activationInfo.ViewDataDictionaryType,
- context.ViewData);
+ return activationInfo.CreateViewDataNested(context.ViewData);
}
return context.ViewData;
@@ -96,6 +100,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor
return new PageActivationInfo
{
ViewDataDictionaryType = viewDataType,
+ CreateViewDataNested = GetCreateViewDataNested(viewDataType),
+ CreateViewDataRoot = GetCreateViewDataRoot(viewDataType),
PropertyActivators = PropertyActivator.GetPropertiesToActivate(
type,
typeof(RazorInjectAttribute),
@@ -104,6 +110,41 @@ namespace Microsoft.AspNetCore.Mvc.Razor
};
}
+ private CreateViewDataNested 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(castNewCall, parameters);
+ return lambda.Compile();
+ }
+
+ private CreateViewDataRoot GetCreateViewDataRoot(Type viewDataDictionaryType)
+ {
+ var parameterTypes = new Type[] {
+ typeof(IModelMetadataProvider),
+ typeof(ModelStateDictionary) };
+ var matchingConstructor = viewDataDictionaryType.GetConstructor(parameterTypes);
+ Debug.Assert(matchingConstructor != null);
+
+ var parameters = new ParameterExpression[] {
+ Expression.Parameter(parameterTypes[0]),
+ Expression.Parameter(parameterTypes[1]) };
+ var newExpression = Expression.New(matchingConstructor, parameters);
+ var castNewCall = Expression.Convert(
+ newExpression,
+ typeof(ViewDataDictionary));
+ var lambda = Expression.Lambda(castNewCall, parameters);
+ return lambda.Compile();
+ }
+
+
private PropertyActivator CreateActivateInfo(PropertyInfo property)
{
Func valueAccessor;
@@ -147,6 +188,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public Type ViewDataDictionaryType { get; set; }
+ public CreateViewDataNested CreateViewDataNested { get; set; }
+
+ public CreateViewDataRoot CreateViewDataRoot { get; set; }
+
public Action