[Perf] RazorPage.CreateModelExpression is allocating expression names

Fixes #4469
This commit is contained in:
mnltejaswini 2016-04-18 16:14:56 -07:00
parent 4b4d67e48e
commit f1fe5e26fc
35 changed files with 334 additions and 140 deletions

View File

@ -18,5 +18,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor
/// Name the method to create <c>ModelExpression</c>s.
/// </summary>
public string CreateModelExpressionMethodName { get; set; }
/// <summary>
/// Gets or sets the name of the <c>IModelExpressionProvider</c>.
/// </summary>
public string ModelExpressionProviderPropertyName { get; set; }
/// <summary>
/// Gets or sets the property name of the <c>ViewDataDictionary</c>.
/// </summary>
public string ViewDataPropertyName { get; set; }
}
}

View File

@ -24,6 +24,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor
{
private const string BaseType = "Microsoft.AspNetCore.Mvc.Razor.RazorPage";
private const string HtmlHelperPropertyName = "Html";
private const string ModelExpressionProviderProperty = "ModelExpressionProvider";
private const string ViewDataProperty = "ViewData";
private static readonly string[] _defaultNamespaces = new[]
{
@ -32,6 +34,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
"System.Collections.Generic",
"Microsoft.AspNetCore.Mvc",
"Microsoft.AspNetCore.Mvc.Rendering",
"Microsoft.AspNetCore.Mvc.ViewFeatures",
};
private static readonly Chunk[] _defaultInheritedChunks = new Chunk[]
{
@ -39,6 +42,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
new InjectChunk("Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper", "Json"),
new InjectChunk("Microsoft.AspNetCore.Mvc.IViewComponentHelper", "Component"),
new InjectChunk("Microsoft.AspNetCore.Mvc.IUrlHelper", "Url"),
new InjectChunk("Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider", ModelExpressionProviderProperty),
new AddTagHelperChunk
{
LookupText = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor"
@ -206,7 +210,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
/// </summary>
public virtual string ModelExpressionType
{
get { return "Microsoft.AspNetCore.Mvc.Rendering.ModelExpression"; }
get { return "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression"; }
}
/// <summary>
@ -217,6 +221,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor
get { return "CreateModelExpression"; }
}
/// <summary>
/// Gets the property name for <c>IModelExpressionProvider</c>.
/// </summary>
public virtual string ModelExpressionProvider
{
get { return ModelExpressionProviderProperty; }
}
/// <summary>
/// Gets the property name for <c>ViewDataDictionary</c>.
/// </summary>
public virtual string ViewDataPropertyName
{
get { return ViewDataProperty; }
}
// Internal for testing
internal ChunkInheritanceUtility ChunkInheritanceUtility
{
@ -317,7 +337,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor
new GeneratedTagHelperAttributeContext
{
ModelExpressionTypeName = ModelExpressionType,
CreateModelExpressionMethodName = CreateModelExpressionMethod
CreateModelExpressionMethodName = CreateModelExpressionMethod,
ModelExpressionProviderPropertyName = ModelExpressionProviderProperty,
ViewDataPropertyName = ViewDataProperty,
});
}

View File

@ -63,7 +63,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor
if (attributeDescriptor.TypeName.Equals(_context.ModelExpressionTypeName, StringComparison.Ordinal))
{
writer
.WriteStartMethodInvocation(_context.CreateModelExpressionMethodName)
.WriteStartInstanceMethodInvocation(_context.ModelExpressionProviderPropertyName, _context.CreateModelExpressionMethodName)
.Write(_context.ViewDataPropertyName)
.WriteParameterSeparator()
.Write(ModelLambdaVariableName)
.Write(" => ");
if (!complexValue)

View File

@ -186,22 +186,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor
return string.Format(CultureInfo.CurrentCulture, GetString("RazorPage_CannotFlushWhileInAWritingScope"), p0, p1);
}
/// <summary>
/// The {0} was unable to provide metadata for expression '{1}'.
/// </summary>
internal static string RazorPage_NullModelMetadata
{
get { return GetString("RazorPage_NullModelMetadata"); }
}
/// <summary>
/// The {0} was unable to provide metadata for expression '{1}'.
/// </summary>
internal static string FormatRazorPage_NullModelMetadata(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("RazorPage_NullModelMetadata"), p0, p1);
}
/// <summary>
/// {0} invocation in '{1}' is invalid. {0} can only be called from a layout page.
/// </summary>

View File

@ -35,6 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
private Func<ViewContext, object> _jsonHelperAccessor;
private Func<ViewContext, object> _diagnosticSourceAccessor;
private Func<ViewContext, object> _htmlEncoderAccessor;
private Func<ViewContext, object> _modelExpressionProviderAccessor;
/// <summary>
/// Initializes a new instance of the <see cref="RazorPageActivator"/> class.
@ -44,7 +45,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor
IUrlHelperFactory urlHelperFactory,
IJsonHelper jsonHelper,
DiagnosticSource diagnosticSource,
HtmlEncoder htmlEncoder)
HtmlEncoder htmlEncoder,
IModelExpressionProvider modelExpressionProvider)
{
_activationInfo = new ConcurrentDictionary<Type, PageActivationInfo>();
_metadataProvider = metadataProvider;
@ -52,6 +54,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
_jsonHelperAccessor = context => jsonHelper;
_diagnosticSourceAccessor = context => diagnosticSource;
_htmlEncoderAccessor = context => htmlEncoder;
_modelExpressionProviderAccessor = context => modelExpressionProvider;
}
/// <inheritdoc />
@ -190,6 +193,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor
{
valueAccessor = _htmlEncoderAccessor;
}
else if (property.PropertyType == typeof(IModelExpressionProvider))
{
valueAccessor = _modelExpressionProviderAccessor;
}
else
{
valueAccessor = context =>

View File

@ -18,8 +18,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor
/// <typeparam name="TModel">The type of the view data model.</typeparam>
public abstract class RazorPage<TModel> : RazorPage
{
private IModelMetadataProvider _provider;
/// <summary>
/// Gets the Model property of the <see cref="ViewData"/> property.
/// </summary>
@ -37,43 +35,5 @@ namespace Microsoft.AspNetCore.Mvc.Razor
[RazorInject]
public ViewDataDictionary<TModel> ViewData { get; set; }
/// <summary>
/// Gets or sets the expression text cache for model expressions.
/// </summary>
[RazorInject]
private ExpressionTextCache ExpressionTextCache { get; set; }
/// <summary>
/// Returns a <see cref="ModelExpression"/> instance describing the given <paramref name="expression"/>.
/// </summary>
/// <typeparam name="TValue">The type of the <paramref name="expression"/> result.</typeparam>
/// <param name="expression">An expression to be evaluated against the current model.</param>
/// <returns>A new <see cref="ModelExpression"/> instance describing the given <paramref name="expression"/>.
/// </returns>
/// <remarks>
/// Compiler normally infers <typeparamref name="TValue"/> from the given <paramref name="expression"/>.
/// </remarks>
public ModelExpression CreateModelExpression<TValue>(Expression<Func<TModel, TValue>> expression)
{
if (expression == null)
{
throw new ArgumentNullException(nameof(expression));
}
if (_provider == null)
{
_provider = Context.RequestServices.GetRequiredService<IModelMetadataProvider>();
}
var name = ExpressionHelper.GetExpressionText(expression, ExpressionTextCache);
var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, ViewData, _provider);
if (modelExplorer == null)
{
throw new InvalidOperationException(
Resources.FormatRazorPage_NullModelMetadata(nameof(IModelMetadataProvider), name));
}
return new ModelExpression(name, modelExplorer);
}
}
}

View File

@ -150,9 +150,6 @@
<data name="RazorPage_CannotFlushWhileInAWritingScope" xml:space="preserve">
<value>The {0} operation cannot be performed while inside a writing scope in '{1}'.</value>
</data>
<data name="RazorPage_NullModelMetadata" xml:space="preserve">
<value>The {0} was unable to provide metadata for expression '{1}'.</value>
</data>
<data name="RazorPage_MethodCannotBeCalled" xml:space="preserve">
<value>{0} invocation in '{1}' is invalid. {0} can only be called from a layout page.</value>
</data>

View File

@ -115,6 +115,7 @@ namespace Microsoft.Extensions.DependencyInjection
services.TryAddTransient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>));
services.TryAddSingleton<IHtmlGenerator, DefaultHtmlGenerator>();
services.TryAddSingleton<ExpressionTextCache>();
services.TryAddSingleton<IModelExpressionProvider, ModelExpressionProvider>();
//
// JSON Helper

View File

@ -874,6 +874,22 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
return string.Format(CultureInfo.CurrentCulture, GetString("ValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated"), p0, p1);
}
/// <summary>
/// The {0} was unable to provide metadata for expression '{1}'.
/// </summary>
internal static string CreateModelExpression_NullModelMetadata
{
get { return GetString("CreateModelExpression_NullModelMetadata"); }
}
/// <summary>
/// The {0} was unable to provide metadata for expression '{1}'.
/// </summary>
internal static string FormatCreateModelExpression_NullModelMetadata(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("CreateModelExpression_NullModelMetadata"), p0, p1);
}
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
@ -280,4 +280,7 @@
<data name="ValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated" xml:space="preserve">
<value>The type '{0}' cannot be activated by '{1}' because it is either a value type, an interface, an abstract class or an open generic type.</value>
</data>
<data name="CreateModelExpression_NullModelMetadata" xml:space="preserve">
<value>The {0} was unable to provide metadata for expression '{1}'.</value>
</data>
</root>

View File

@ -0,0 +1,27 @@
// 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.Linq.Expressions;
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
{
/// <summary>
/// Provides <see cref="ModelExpression"/> for a Lambda expression.
/// </summary>
public interface IModelExpressionProvider
{
/// <summary>
/// Returns a <see cref="ModelExpression"/> instance describing the given <paramref name="expression"/>.
/// </summary>
/// <typeparam name="TModel">The type of the <paramref name="viewData"/>'s <see cref="ViewDataDictionary{T}.Model"/>.</typeparam>
/// <typeparam name="TValue">The type of the <paramref name="expression"/> result.</typeparam>
/// <param name="viewData">The <see cref="ViewDataDictionary{TModel}"/> containing the <see cref="ViewDataDictionary{T}.Model"/>
/// against which <paramref name="expression"/> is evaluated. </param>
/// <param name="expression">An expression to be evaluated against the current model.</param>
/// <returns>A new <see cref="ModelExpression"/> instance describing the given <paramref name="expression"/>.</returns>
ModelExpression CreateModelExpression<TModel, TValue>(
ViewDataDictionary<TModel> viewData,
Expression<Func<TModel, TValue>> expression);
}
}

View File

@ -5,7 +5,7 @@ using System;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
namespace Microsoft.AspNetCore.Mvc.Rendering
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
{
/// <summary>
/// Describes an <see cref="System.Linq.Expressions.Expression"/> passed to a tag helper.

View File

@ -0,0 +1,68 @@
// 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.Linq.Expressions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
namespace Microsoft.AspNetCore.Mvc.ViewFeatures
{
/// <summary>
/// A default implementation of <see cref="IModelMetadataProvider"/>.
/// </summary>
public class ModelExpressionProvider : IModelExpressionProvider
{
private readonly IModelMetadataProvider _modelMetadataProvider;
private readonly ExpressionTextCache _expressionTextCache;
/// <summary>
/// Creates a new <see cref="ModelExpressionProvider"/>.
/// </summary>
/// <param name="modelMetadataProvider">The <see cref="IModelMetadataProvider"/>.</param>
/// <param name="expressionTextCache">The <see cref="ExpressionTextCache"/>.</param>
public ModelExpressionProvider(
IModelMetadataProvider modelMetadataProvider,
ExpressionTextCache expressionTextCache)
{
if (modelMetadataProvider == null)
{
throw new ArgumentNullException(nameof(modelMetadataProvider));
}
if (expressionTextCache == null)
{
throw new ArgumentNullException(nameof(expressionTextCache));
}
_modelMetadataProvider = modelMetadataProvider;
_expressionTextCache = expressionTextCache;
}
/// <inheritdoc />
public ModelExpression CreateModelExpression<TModel, TValue>(
ViewDataDictionary<TModel> viewData,
Expression<Func<TModel, TValue>> expression)
{
if (viewData == null)
{
throw new ArgumentNullException(nameof(viewData));
}
if (expression == null)
{
throw new ArgumentNullException(nameof(expression));
}
var name = ExpressionHelper.GetExpressionText(expression, _expressionTextCache);
var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, viewData, _modelMetadataProvider);
if (modelExplorer == null)
{
throw new InvalidOperationException(
Resources.FormatCreateModelExpression_NullModelMetadata(nameof(IModelMetadataProvider), name));
}
return new ModelExpression(name, modelExplorer);
}
}
}

View File

@ -1,7 +1,7 @@
// 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 Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace Microsoft.AspNetCore.Mvc.Razor

View File

@ -139,33 +139,33 @@ namespace Microsoft.AspNetCore.Mvc.Razor
documentAbsoluteIndex: 33,
documentLineIndex: 2,
documentCharacterIndex: 14,
generatedAbsoluteIndex: 597,
generatedLineIndex: 16,
generatedAbsoluteIndex: 647,
generatedLineIndex: 17,
generatedCharacterIndex: 48,
contentLength: 91),
BuildLineMapping(
documentAbsoluteIndex: 7,
documentLineIndex: 0,
documentCharacterIndex: 7,
generatedAbsoluteIndex: 779,
generatedLineIndex: 18,
generatedAbsoluteIndex: 829,
generatedLineIndex: 19,
generatedCharacterIndex: 28,
contentLength: 8),
BuildLineMapping(
documentAbsoluteIndex: 145,
documentLineIndex: 4,
documentCharacterIndex: 17,
generatedAbsoluteIndex: 2242,
generatedLineIndex: 47,
generatedCharacterIndex: 99,
generatedAbsoluteIndex: 2523,
generatedLineIndex: 50,
generatedCharacterIndex: 133,
contentLength: 3),
BuildLineMapping(
documentAbsoluteIndex: 172,
documentLineIndex: 5,
documentCharacterIndex: 18,
generatedAbsoluteIndex: 2575,
generatedLineIndex: 53,
generatedCharacterIndex: 91,
generatedAbsoluteIndex: 2890,
generatedLineIndex: 56,
generatedCharacterIndex: 125,
contentLength: 5),
};
@ -213,16 +213,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor
documentAbsoluteIndex: 13,
documentLineIndex: 0,
documentCharacterIndex: 13,
generatedAbsoluteIndex: 1295,
generatedLineIndex: 32,
generatedAbsoluteIndex: 1492,
generatedLineIndex: 34,
generatedCharacterIndex: 13,
contentLength: 4),
BuildLineMapping(
documentAbsoluteIndex: 43,
documentLineIndex: 2,
documentCharacterIndex: 5,
generatedAbsoluteIndex: 1379,
generatedLineIndex: 37,
generatedAbsoluteIndex: 1576,
generatedLineIndex: 39,
generatedCharacterIndex: 6,
contentLength: 21),
};
@ -611,7 +611,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor
new GeneratedTagHelperAttributeContext
{
ModelExpressionTypeName = ModelExpressionType,
CreateModelExpressionMethodName = CreateModelExpressionMethod
CreateModelExpressionMethodName = CreateModelExpressionMethod,
ModelExpressionProviderPropertyName = ModelExpressionProvider,
ViewDataPropertyName = ViewDataPropertyName
});
}
@ -664,7 +666,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor
new GeneratedTagHelperAttributeContext
{
ModelExpressionTypeName = ModelExpressionType,
CreateModelExpressionMethodName = CreateModelExpressionMethod
CreateModelExpressionMethodName = CreateModelExpressionMethod,
ModelExpressionProviderPropertyName = ModelExpressionProvider,
ViewDataPropertyName = ViewDataPropertyName
});
}

View File

@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor;
using Microsoft.AspNetCore.Razor.Chunks;
using Microsoft.AspNetCore.Razor.Compilation.TagHelpers;

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public class MvcTagHelperAttributeValueCodeRendererTest
{
[Theory]
[InlineData("SomeType", "SomeType", "SomeMethod(__model => __model.MyValue)")]
[InlineData("SomeType", "SomeType", "Provider.SomeMethod(ViewData, __model => __model.MyValue)")]
[InlineData("SomeType", "SomeType2", "MyValue")]
public void RenderAttributeValue_RendersModelExpressionsCorrectly(
string modelExpressionType,
@ -24,7 +24,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor
new GeneratedTagHelperAttributeContext
{
ModelExpressionTypeName = modelExpressionType,
CreateModelExpressionMethodName = "SomeMethod"
CreateModelExpressionMethodName = "SomeMethod",
ModelExpressionProviderPropertyName = "Provider",
ViewDataPropertyName = "ViewData"
});
var attributeDescriptor = new TagHelperAttributeDescriptor
{

View File

@ -16,6 +16,8 @@ namespace Asp
}
#line hidden
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -30,6 +30,8 @@ using MyNamespace
#line hidden
{ get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -37,6 +37,8 @@ var __modelHelper = default(MyModel);
#line hidden
{ get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -53,6 +53,8 @@ var __modelHelper = default(MyModel);
#line hidden
{ get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -21,6 +21,8 @@ var __modelHelper = default(System.Collections.IEnumerable);
}
#line hidden
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -5,6 +5,7 @@ namespace Asp
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Threading.Tasks;
public class testfiles_input_modelexpressiontaghelper_cshtml : Microsoft.AspNetCore.Mvc.Razor.RazorPage<DateTime>
@ -30,6 +31,8 @@ var __modelHelper = default(DateTime);
}
#line hidden
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
@ -45,13 +48,13 @@ var __modelHelper = default(DateTime);
{
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.InputTestTagHelper>();
#line 5 "testfiles/input/modelexpressiontaghelper.cshtml"
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper.For = CreateModelExpression(__model => __model.Now);
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Now);
#line default
#line hidden
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.InputTestTagHelper>();
#line 6 "testfiles/input/modelexpressiontaghelper.cshtml"
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper.For = CreateModelExpression(__model => Model);
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => Model);
#line default
#line hidden

View File

@ -21,6 +21,8 @@ var __modelHelper = default(System.Collections.IEnumerable);
}
#line hidden
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -25,6 +25,8 @@ namespace Asp
#line hidden
{ get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -6,6 +6,7 @@ namespace Asp
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Threading.Tasks;
public class TestFiles_Input_Basic_cshtml : Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
@ -16,6 +17,8 @@ namespace Asp
}
#line hidden
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -12,6 +12,7 @@ using MyNamespace
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Threading.Tasks;
public class TestFiles_Input_Inject_cshtml : Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
@ -24,6 +25,8 @@ using MyNamespace
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public MyApp MyPropertyName { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -6,6 +6,7 @@ namespace Asp
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Threading.Tasks;
public class TestFiles_Input_InjectWithModel_cshtml : Microsoft.AspNetCore.Mvc.Razor.RazorPage<MyModel>
@ -20,6 +21,8 @@ namespace Asp
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public MyService<MyModel> Html { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -6,6 +6,7 @@ namespace Asp
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Threading.Tasks;
public class TestFiles_Input_InjectWithSemicolon_cshtml : Microsoft.AspNetCore.Mvc.Razor.RazorPage<MyModel>
@ -24,6 +25,8 @@ namespace Asp
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public MyService<MyModel> Html2 { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -6,6 +6,7 @@ namespace Asp
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Threading.Tasks;
public class TestFiles_Input_Model_cshtml : Microsoft.AspNetCore.Mvc.Razor.RazorPage<System.Collections.IEnumerable>
@ -16,6 +17,8 @@ namespace Asp
}
#line hidden
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -6,6 +6,7 @@ namespace Asp
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Threading.Tasks;
public class TestFiles_Input_ModelExpressionTagHelper_cshtml : Microsoft.AspNetCore.Mvc.Razor.RazorPage<DateTime>
@ -24,6 +25,8 @@ namespace Asp
}
#line hidden
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
@ -48,7 +51,7 @@ namespace Asp
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.InputTestTagHelper>();
__tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper);
#line 5 "TestFiles/Input/ModelExpressionTagHelper.cshtml"
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper.For = CreateModelExpression(__model => __model.Now);
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Now);
#line default
#line hidden
@ -67,7 +70,7 @@ __Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper.For = CreateModelExpression(
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.InputTestTagHelper>();
__tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper);
#line 6 "TestFiles/Input/ModelExpressionTagHelper.cshtml"
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper.For = CreateModelExpression(__model => Model);
__Microsoft_AspNetCore_Mvc_Razor_InputTestTagHelper.For = ModelExpressionProvider.CreateModelExpression(ViewData, __model => Model);
#line default
#line hidden

View File

@ -6,6 +6,7 @@ namespace Asp
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Threading.Tasks;
public class TestFiles_Input__ViewImports_cshtml : Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
@ -18,6 +19,8 @@ namespace Asp
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public IHtmlHelper<dynamic> Model { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }

View File

@ -29,6 +29,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public void Activate_ActivatesAndContextualizesPropertiesOnViews()
{
// Arrange
var modelMetadataProvider = new EmptyModelMetadataProvider();
var modelExpressionProvider = new ModelExpressionProvider(modelMetadataProvider, new ExpressionTextCache());
var urlHelperFactory = new UrlHelperFactory();
var jsonHelper = new JsonHelper(new JsonOutputFormatter());
var htmlEncoder = new HtmlTestEncoder();
@ -38,7 +40,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor
urlHelperFactory,
jsonHelper,
diagnosticSource,
htmlEncoder);
htmlEncoder,
modelExpressionProvider);
var instance = new TestRazorPage();
@ -84,12 +87,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public void Activate_ThrowsIfTheViewDoesNotDeriveFromRazorViewOfT()
{
// Arrange
var modelMetadataProvider = new EmptyModelMetadataProvider();
var modelExpressionProvider = new ModelExpressionProvider(modelMetadataProvider, new ExpressionTextCache());
var activator = new RazorPageActivator(
new EmptyModelMetadataProvider(),
modelMetadataProvider,
new UrlHelperFactory(),
new JsonHelper(new JsonOutputFormatter()),
new DiagnosticListener("Microsoft.AspNetCore"),
new HtmlTestEncoder());
new HtmlTestEncoder(),
modelExpressionProvider);
var instance = new DoesNotDeriveFromRazorPageOfT();
@ -120,12 +126,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public void Activate_InstantiatesNewViewDataDictionaryType_IfTheTypeDoesNotMatch()
{
// Arrange
var modelMetadataProvider = new EmptyModelMetadataProvider();
var modelExpressionProvider = new ModelExpressionProvider(modelMetadataProvider, new ExpressionTextCache());
var activator = new RazorPageActivator(
new EmptyModelMetadataProvider(),
modelMetadataProvider,
new UrlHelperFactory(),
new JsonHelper(new JsonOutputFormatter()),
new DiagnosticListener("Microsoft.AspNetCore.Mvc"),
new HtmlTestEncoder());
new HtmlTestEncoder(),
modelExpressionProvider);
var instance = new TestRazorPage();
var myService = new MyService();
@ -164,12 +174,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public void Activate_UsesPassedInViewDataDictionaryInstance_IfPassedInTypeMatches()
{
// Arrange
var modelMetadataProvider = new EmptyModelMetadataProvider();
var modelExpressionProvider = new ModelExpressionProvider(modelMetadataProvider, new ExpressionTextCache());
var activator = new RazorPageActivator(
new EmptyModelMetadataProvider(),
modelMetadataProvider,
new UrlHelperFactory(),
new JsonHelper(new JsonOutputFormatter()),
new DiagnosticListener("Microsoft.AspNetCore.Mvc"),
new HtmlTestEncoder());
new HtmlTestEncoder(),
modelExpressionProvider);
var instance = new TestRazorPage();
var myService = new MyService();
var helper = Mock.Of<IHtmlHelper<object>>();
@ -207,12 +221,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public void Activate_DeterminesModelTypeFromProperty()
{
// Arrange
var modelMetadataProvider = new EmptyModelMetadataProvider();
var modelExpressionProvider = new ModelExpressionProvider(modelMetadataProvider, new ExpressionTextCache());
var activator = new RazorPageActivator(
new EmptyModelMetadataProvider(),
modelMetadataProvider,
new UrlHelperFactory(),
new JsonHelper(new JsonOutputFormatter()),
new DiagnosticListener("Microsoft.AspNetCore.Mvc"),
new HtmlTestEncoder());
new HtmlTestEncoder(),
modelExpressionProvider);
var instance = new DoesNotDeriveFromRazorPageOfTButHasModelProperty();
var myService = new MyService();
var helper = Mock.Of<IHtmlHelper<object>>();
@ -247,12 +265,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public void Activate_Throws_WhenViewDataPropertyHasIncorrectType()
{
// Arrange
var modelMetadataProvider = new EmptyModelMetadataProvider();
var modelExpressionProvider = new ModelExpressionProvider(modelMetadataProvider, new ExpressionTextCache());
var activator = new RazorPageActivator(
new EmptyModelMetadataProvider(),
modelMetadataProvider,
new UrlHelperFactory(),
new JsonHelper(new JsonOutputFormatter()),
new DiagnosticListener("Microsoft.AspNetCore.Mvc"),
new HtmlTestEncoder());
new HtmlTestEncoder(),
modelExpressionProvider);
var instance = new HasIncorrectViewDataPropertyType();
var collection = new ServiceCollection();
@ -279,12 +301,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public void Activate_CanGetUrlHelperFromDependencyInjection()
{
// Arrange
var modelMetadataProvider = new EmptyModelMetadataProvider();
var modelExpressionProvider = new ModelExpressionProvider(modelMetadataProvider, new ExpressionTextCache());
var activator = new RazorPageActivator(
new EmptyModelMetadataProvider(),
modelMetadataProvider,
new UrlHelperFactory(),
new JsonHelper(new JsonOutputFormatter()),
new DiagnosticListener("Microsoft.AspNetCore.Mvc"),
new HtmlTestEncoder());
new HtmlTestEncoder(),
modelExpressionProvider);
var instance = new HasUnusualIUrlHelperProperty();
// IUrlHelperFactory should not be used. But set it up to match a real configuration.

View File

@ -148,7 +148,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
var page = CreatePage(viewContext);
// Act
var result = page.CreateModelExpression(expression);
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, expression);
// Assert
Assert.NotNull(result);
@ -168,7 +168,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
var page = CreatePage(viewContext);
// Act
var result = page.CreateModelExpression(expression);
var result = page.ModelExpressionProvider.CreateModelExpression(page.ViewData, expression);
// Assert
Assert.NotNull(result);
@ -183,6 +183,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
{
ViewContext = viewContext,
ViewData = (ViewDataDictionary<string>)viewContext.ViewData,
ModelExpressionProvider = CreateModelExpressionProvider(),
};
}
@ -192,6 +193,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
{
ViewContext = viewContext,
ViewData = (ViewDataDictionary<RecursiveModel>)viewContext.ViewData,
ModelExpressionProvider = CreateModelExpressionProvider(),
};
}
@ -201,9 +203,20 @@ namespace Microsoft.AspNetCore.Mvc.Razor
{
ViewContext = viewContext,
ViewData = (ViewDataDictionary<RazorPageCreateModelExpressionModel>)viewContext.ViewData,
ModelExpressionProvider = CreateModelExpressionProvider(),
};
}
private static IModelExpressionProvider CreateModelExpressionProvider()
{
var provider = new TestModelMetadataProvider();
var modelExpressionProvider = new ModelExpressionProvider(
provider,
new ExpressionTextCache());
return modelExpressionProvider;
}
private static ViewContext CreateViewContext()
{
var provider = new TestModelMetadataProvider();
@ -227,16 +240,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor
new HtmlHelperOptions());
}
public class IdentityRazorPage : RazorPage<string>
public class IdentityRazorPage : TestRazorPage<string>
{
public ModelExpression CreateModelExpression1()
{
return CreateModelExpression(m => m);
return ModelExpressionProvider.CreateModelExpression(ViewData, m => m);
}
public ModelExpression CreateModelExpression2()
{
return CreateModelExpression(m => Model);
return ModelExpressionProvider.CreateModelExpression(ViewData, m => Model);
}
public override Task ExecuteAsync()
@ -245,21 +258,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
}
public class NotQuiteIdentityRazorPage : RazorPage<RecursiveModel>
public class NotQuiteIdentityRazorPage : TestRazorPage<RecursiveModel>
{
public ModelExpression CreateModelExpression1()
{
return CreateModelExpression(m => m.Model);
return ModelExpressionProvider.CreateModelExpression(ViewData, m => m.Model);
}
public ModelExpression CreateModelExpression2()
{
return CreateModelExpression(m => ViewData.Model);
return ModelExpressionProvider.CreateModelExpression(ViewData, m => ViewData.Model);
}
public ModelExpression CreateModelExpression3()
{
return CreateModelExpression(m => ViewContext.ViewData.Model);
return ModelExpressionProvider.CreateModelExpression(ViewData, m => ViewContext.ViewData.Model);
}
public override Task ExecuteAsync()
@ -268,7 +281,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
}
private class TestRazorPage : RazorPage<RazorPageCreateModelExpressionModel>
private class TestRazorPage : TestRazorPage<RazorPageCreateModelExpressionModel>
{
public override Task ExecuteAsync()
{
@ -276,6 +289,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
}
public class TestRazorPage<TModel> : RazorPage<TModel>
{
public IModelExpressionProvider ModelExpressionProvider { get; set; }
public override Task ExecuteAsync()
{
throw new NotImplementedException();
}
}
public class RecursiveModel
{
public RecursiveModel Model { get; set; }

View File

@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.WebEncoders.Testing;
@ -69,12 +70,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor
private static TestRazorPage CreateTestRazorPage()
{
var modelMetadataProvider = new EmptyModelMetadataProvider();
var modelExpressionProvider = new ModelExpressionProvider(modelMetadataProvider, new ExpressionTextCache());
var activator = new RazorPageActivator(
new EmptyModelMetadataProvider(),
modelMetadataProvider,
new UrlHelperFactory(),
new JsonHelper(new Formatters.JsonOutputFormatter()),
new DiagnosticListener("Microsoft.AspNetCore"),
new HtmlTestEncoder());
new HtmlTestEncoder(),
modelExpressionProvider);
var serviceProvider = new Mock<IServiceProvider>();
var typeActivator = new TypeActivatorCache();