diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/GeneratedTagHelperAttributeContext.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/GeneratedTagHelperAttributeContext.cs index ccdf885676..15eae0b247 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/GeneratedTagHelperAttributeContext.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/GeneratedTagHelperAttributeContext.cs @@ -18,5 +18,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor /// Name the method to create ModelExpressions. /// public string CreateModelExpressionMethodName { get; set; } + + /// + /// Gets or sets the name of the IModelExpressionProvider. + /// + public string ModelExpressionProviderPropertyName { get; set; } + + /// + /// Gets or sets the property name of the ViewDataDictionary. + /// + public string ViewDataPropertyName { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcRazorHost.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcRazorHost.cs index a841d231bf..482880d586 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcRazorHost.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcRazorHost.cs @@ -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 /// public virtual string ModelExpressionType { - get { return "Microsoft.AspNetCore.Mvc.Rendering.ModelExpression"; } + get { return "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression"; } } /// @@ -217,6 +221,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor get { return "CreateModelExpression"; } } + /// + /// Gets the property name for IModelExpressionProvider. + /// + public virtual string ModelExpressionProvider + { + get { return ModelExpressionProviderProperty; } + } + + /// + /// Gets the property name for ViewDataDictionary. + /// + 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, }); } diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcTagHelperAttributeValueCodeRenderer.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcTagHelperAttributeValueCodeRenderer.cs index 09d1cd30cc..b76f78a8d2 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcTagHelperAttributeValueCodeRenderer.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcTagHelperAttributeValueCodeRenderer.cs @@ -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) diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Mvc.Razor/Properties/Resources.Designer.cs index a89c641c01..e1c2a734e6 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor/Properties/Resources.Designer.cs @@ -186,22 +186,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor return string.Format(CultureInfo.CurrentCulture, GetString("RazorPage_CannotFlushWhileInAWritingScope"), p0, p1); } - /// - /// The {0} was unable to provide metadata for expression '{1}'. - /// - internal static string RazorPage_NullModelMetadata - { - get { return GetString("RazorPage_NullModelMetadata"); } - } - - /// - /// The {0} was unable to provide metadata for expression '{1}'. - /// - internal static string FormatRazorPage_NullModelMetadata(object p0, object p1) - { - return string.Format(CultureInfo.CurrentCulture, GetString("RazorPage_NullModelMetadata"), p0, p1); - } - /// /// {0} invocation in '{1}' is invalid. {0} can only be called from a layout page. /// diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageActivator.cs b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageActivator.cs index 2bdcf10fcc..563b67e205 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageActivator.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageActivator.cs @@ -35,6 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor private Func _jsonHelperAccessor; private Func _diagnosticSourceAccessor; private Func _htmlEncoderAccessor; + private Func _modelExpressionProviderAccessor; /// /// Initializes a new instance of the 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(); _metadataProvider = metadataProvider; @@ -52,6 +54,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor _jsonHelperAccessor = context => jsonHelper; _diagnosticSourceAccessor = context => diagnosticSource; _htmlEncoderAccessor = context => htmlEncoder; + _modelExpressionProviderAccessor = context => modelExpressionProvider; } /// @@ -190,6 +193,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor { valueAccessor = _htmlEncoderAccessor; } + else if (property.PropertyType == typeof(IModelExpressionProvider)) + { + valueAccessor = _modelExpressionProviderAccessor; + } else { valueAccessor = context => diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageOfT.cs b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageOfT.cs index 7f54d0e730..807a645060 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageOfT.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageOfT.cs @@ -18,8 +18,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor /// The type of the view data model. public abstract class RazorPage : RazorPage { - private IModelMetadataProvider _provider; - /// /// Gets the Model property of the property. /// @@ -37,43 +35,5 @@ namespace Microsoft.AspNetCore.Mvc.Razor [RazorInject] public ViewDataDictionary ViewData { get; set; } - /// - /// Gets or sets the expression text cache for model expressions. - /// - [RazorInject] - private ExpressionTextCache ExpressionTextCache { get; set; } - - /// - /// Returns a instance describing the given . - /// - /// The type of the result. - /// An expression to be evaluated against the current model. - /// A new instance describing the given . - /// - /// - /// Compiler normally infers from the given . - /// - public ModelExpression CreateModelExpression(Expression> expression) - { - if (expression == null) - { - throw new ArgumentNullException(nameof(expression)); - } - - if (_provider == null) - { - _provider = Context.RequestServices.GetRequiredService(); - } - - 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); - } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/Resources.resx b/src/Microsoft.AspNetCore.Mvc.Razor/Resources.resx index caac824d01..f44490e3db 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/Resources.resx +++ b/src/Microsoft.AspNetCore.Mvc.Razor/Resources.resx @@ -150,9 +150,6 @@ The {0} operation cannot be performed while inside a writing scope in '{1}'. - - The {0} was unable to provide metadata for expression '{1}'. - {0} invocation in '{1}' is invalid. {0} can only be called from a layout page. diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs index 05c913720f..ad743dd43d 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs @@ -115,6 +115,7 @@ namespace Microsoft.Extensions.DependencyInjection services.TryAddTransient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>)); services.TryAddSingleton(); services.TryAddSingleton(); + services.TryAddSingleton(); // // JSON Helper diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Properties/Resources.Designer.cs index 7557de5a97..a3ae42d54f 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Properties/Resources.Designer.cs @@ -874,6 +874,22 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures return string.Format(CultureInfo.CurrentCulture, GetString("ValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated"), p0, p1); } + /// + /// The {0} was unable to provide metadata for expression '{1}'. + /// + internal static string CreateModelExpression_NullModelMetadata + { + get { return GetString("CreateModelExpression_NullModelMetadata"); } + } + + /// + /// The {0} was unable to provide metadata for expression '{1}'. + /// + 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); diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Resources.resx b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Resources.resx index d1f2131bc6..61c168de0c 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Resources.resx +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Resources.resx @@ -1,17 +1,17 @@  - @@ -280,4 +280,7 @@ 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. + + The {0} was unable to provide metadata for expression '{1}'. + \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/IModelExpressionProvider.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/IModelExpressionProvider.cs new file mode 100644 index 0000000000..93f6002eb0 --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/IModelExpressionProvider.cs @@ -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 +{ + /// + /// Provides for a Lambda expression. + /// + public interface IModelExpressionProvider + { + /// + /// Returns a instance describing the given . + /// + /// The type of the 's . + /// The type of the result. + /// The containing the + /// against which is evaluated. + /// An expression to be evaluated against the current model. + /// A new instance describing the given . + ModelExpression CreateModelExpression( + ViewDataDictionary viewData, + Expression> expression); + } +} diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/ModelExpression.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/ModelExpression.cs index 1cd30d28bb..69bcbbb05e 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/ModelExpression.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/ModelExpression.cs @@ -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 { /// /// Describes an passed to a tag helper. diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/ModelExpressionProvider.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/ModelExpressionProvider.cs new file mode 100644 index 0000000000..46c8830068 --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/ModelExpressionProvider.cs @@ -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 +{ + /// + /// A default implementation of . + /// + public class ModelExpressionProvider : IModelExpressionProvider + { + private readonly IModelMetadataProvider _modelMetadataProvider; + private readonly ExpressionTextCache _expressionTextCache; + + /// + /// Creates a new . + /// + /// The . + /// The . + 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; + } + + /// + public ModelExpression CreateModelExpression( + ViewDataDictionary viewData, + Expression> 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); + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/InputTestTagHelper.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/InputTestTagHelper.cs index 67a9d72fd9..4abfc8077c 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/InputTestTagHelper.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/InputTestTagHelper.cs @@ -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 diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcRazorHostTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcRazorHostTest.cs index eafb1d0d27..1ff46f25fa 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcRazorHostTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcRazorHostTest.cs @@ -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 }); } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcRazorParserTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcRazorParserTest.cs index 6ae741445b..7d548ace3a 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcRazorParserTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcRazorParserTest.cs @@ -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; diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcTagHelperAttributeValueCodeRendererTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcTagHelperAttributeValueCodeRendererTest.cs index 7c7dfbb386..d501bf60c7 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcTagHelperAttributeValueCodeRendererTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/MvcTagHelperAttributeValueCodeRendererTest.cs @@ -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 { diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Basic.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Basic.cs index ef7e63e26a..3df1e64e2e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Basic.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Basic.cs @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Inject.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Inject.cs index b8fdb1485a..b55ed58382 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Inject.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Inject.cs @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithModel.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithModel.cs index bbb3c07412..d905c1670c 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithModel.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithModel.cs @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithSemicolon.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithSemicolon.cs index 898d3b0841..6e507fed4f 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithSemicolon.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/InjectWithSemicolon.cs @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Model.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Model.cs index c154b2536e..87f804454b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Model.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/Model.cs @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/ModelExpressionTagHelper.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/ModelExpressionTagHelper.cs index 0d20eeb684..b89a9af85b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/ModelExpressionTagHelper.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/ModelExpressionTagHelper.cs @@ -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 @@ -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(); #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(); #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 diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/MultipleModels.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/MultipleModels.cs index 68de5663a8..11d85e00f4 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/MultipleModels.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/MultipleModels.cs @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/_ViewImports.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/_ViewImports.cs index d9b1f523d2..7101c96129 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/_ViewImports.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/DesignTime/_ViewImports.cs @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Basic.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Basic.cs index 1a700d32e8..b40a8e209c 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Basic.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Basic.cs @@ -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 @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Inject.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Inject.cs index 49359cc947..2be55b2e48 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Inject.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Inject.cs @@ -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 @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithModel.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithModel.cs index 1a08717646..116c92692c 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithModel.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithModel.cs @@ -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 @@ -20,6 +21,8 @@ namespace Asp [Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] public MyService 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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithSemicolon.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithSemicolon.cs index fc5b8a9cd9..2c32449dce 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithSemicolon.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/InjectWithSemicolon.cs @@ -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 @@ -24,6 +25,8 @@ namespace Asp [Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] public MyService 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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Model.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Model.cs index b3dbafa707..d70809eb63 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Model.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/Model.cs @@ -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 @@ -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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/ModelExpressionTagHelper.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/ModelExpressionTagHelper.cs index 1b6d475942..cee84b283a 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/ModelExpressionTagHelper.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/ModelExpressionTagHelper.cs @@ -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 @@ -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(); __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(); __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 diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/_ViewImports.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/_ViewImports.cs index 57c097dfea..a4bf62ad1b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/_ViewImports.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/TestFiles/Output/Runtime/_ViewImports.cs @@ -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 @@ -18,6 +19,8 @@ namespace Asp [Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] public IHtmlHelper 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; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageActivatorTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageActivatorTest.cs index a9b80a25c3..4e58c1375e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageActivatorTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageActivatorTest.cs @@ -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>(); @@ -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>(); @@ -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. diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageCreateModelExpressionTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageCreateModelExpressionTest.cs index 043237bc9c..fa1c14aac9 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageCreateModelExpressionTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageCreateModelExpressionTest.cs @@ -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)viewContext.ViewData, + ModelExpressionProvider = CreateModelExpressionProvider(), }; } @@ -192,6 +193,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor { ViewContext = viewContext, ViewData = (ViewDataDictionary)viewContext.ViewData, + ModelExpressionProvider = CreateModelExpressionProvider(), }; } @@ -201,9 +203,20 @@ namespace Microsoft.AspNetCore.Mvc.Razor { ViewContext = viewContext, ViewData = (ViewDataDictionary)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 + public class IdentityRazorPage : TestRazorPage { 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 + public class NotQuiteIdentityRazorPage : TestRazorPage { 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 + private class TestRazorPage : TestRazorPage { public override Task ExecuteAsync() { @@ -276,6 +289,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor } } + public class TestRazorPage : RazorPage + { + public IModelExpressionProvider ModelExpressionProvider { get; set; } + + public override Task ExecuteAsync() + { + throw new NotImplementedException(); + } + } + public class RecursiveModel { public RecursiveModel Model { get; set; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs index 9ed8b0484b..d1e72c24d1 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs @@ -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(); var typeActivator = new TypeActivatorCache();