diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/ModelExpression.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/ModelExpression.cs
index bf0372884b..d5179f5f93 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Rendering/ModelExpression.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/ModelExpression.cs
@@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
///
/// Describes an passed to a tag helper.
///
- public class ModelExpression
+ public sealed class ModelExpression
{
///
/// Initializes a new instance of the class.
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/GeneratedTagHelperAttributeContext.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/GeneratedTagHelperAttributeContext.cs
new file mode 100644
index 0000000000..296959aeaf
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/GeneratedTagHelperAttributeContext.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Razor.Runtime.TagHelpers;
+
+namespace Microsoft.AspNet.Mvc.Razor
+{
+ ///
+ /// Contains information for the attribute code generation process.
+ ///
+ public class GeneratedTagHelperAttributeContext
+ {
+ ///
+ /// Name of the model expression type.
+ ///
+ public string ModelExpressionTypeName { get; set; }
+
+ ///
+ /// Name the method to create ModelExpressions.
+ ///
+ public string CreateModelExpressionMethodName { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeBuilder.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeBuilder.cs
index ada4b74ac6..91b262b9fd 100644
--- a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeBuilder.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcCSharpCodeBuilder.cs
@@ -11,20 +11,34 @@ namespace Microsoft.AspNet.Mvc.Razor
{
public class MvcCSharpCodeBuilder : CSharpCodeBuilder
{
+ private readonly GeneratedTagHelperAttributeContext _tagHelperAttributeContext;
private readonly string _defaultModel;
private readonly string _activateAttribute;
public MvcCSharpCodeBuilder([NotNull] CodeBuilderContext context,
[NotNull] string defaultModel,
- [NotNull] string activateAttribute)
+ [NotNull] string activateAttribute,
+ [NotNull] GeneratedTagHelperAttributeContext tagHelperAttributeContext)
: base(context)
{
+ _tagHelperAttributeContext = tagHelperAttributeContext;
_defaultModel = defaultModel;
_activateAttribute = activateAttribute;
}
private string Model { get; set; }
+ protected override CSharpCodeVisitor CreateCSharpCodeVisitor([NotNull] CSharpCodeWriter writer,
+ [NotNull] CodeBuilderContext context)
+ {
+ var csharpCodeVisitor = base.CreateCSharpCodeVisitor(writer, context);
+
+ csharpCodeVisitor.TagHelperRenderer.AttributeValueCodeRenderer =
+ new MvcTagHelperAttributeValueCodeRenderer(_tagHelperAttributeContext);
+
+ return csharpCodeVisitor;
+ }
+
protected override CSharpCodeWritingScope BuildClassDeclaration(CSharpCodeWriter writer)
{
// Grab the last model chunk so it gets intellisense.
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHost.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHost.cs
index 7aa114da16..aaf87e13ff 100644
--- a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHost.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHost.cs
@@ -153,6 +153,22 @@ namespace Microsoft.AspNet.Mvc.Razor
get { return "Microsoft.AspNet.Mvc.ActivateAttribute"; }
}
+ ///
+ /// Gets the type name used to represent model expression properties.
+ ///
+ public virtual string ModelExpressionType
+ {
+ get { return "Microsoft.AspNet.Mvc.Rendering.ModelExpression"; }
+ }
+
+ ///
+ /// Gets the method name used to create model expressions.
+ ///
+ public virtual string CreateModelExpressionMethod
+ {
+ get { return "CreateModelExpression"; }
+ }
+
///
public GeneratorResults GenerateCode(string rootRelativePath, Stream inputStream)
{
@@ -173,7 +189,15 @@ namespace Microsoft.AspNet.Mvc.Razor
[NotNull] CodeBuilderContext context)
{
UpdateCodeBuilder(context);
- return new MvcCSharpCodeBuilder(context, DefaultModel, ActivateAttribute);
+
+ return new MvcCSharpCodeBuilder(context,
+ DefaultModel,
+ ActivateAttribute,
+ new GeneratedTagHelperAttributeContext
+ {
+ ModelExpressionTypeName = ModelExpressionType,
+ CreateModelExpressionMethodName = CreateModelExpressionMethod
+ });
}
private void UpdateCodeBuilder(CodeGeneratorContext context)
diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcTagHelperAttributeValueCodeRenderer.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcTagHelperAttributeValueCodeRenderer.cs
new file mode 100644
index 0000000000..1be3000b1d
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcTagHelperAttributeValueCodeRenderer.cs
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNet.Razor.Generator;
+using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
+using Microsoft.AspNet.Razor.TagHelpers;
+
+namespace Microsoft.AspNet.Mvc.Razor
+{
+ ///
+ public class MvcTagHelperAttributeValueCodeRenderer : TagHelperAttributeValueCodeRenderer
+ {
+ private const string ModelLambdaVariableName = "__model";
+
+ private readonly GeneratedTagHelperAttributeContext _context;
+
+ ///
+ /// Instantiates a new instance of .
+ ///
+ /// Contains code generation information for rendering attribute values.
+ public MvcTagHelperAttributeValueCodeRenderer([NotNull] GeneratedTagHelperAttributeContext context)
+ {
+ _context = context;
+ }
+
+ ///
+ /// If the attribute being rendered is of the type
+ /// then a model expression will be
+ /// created by calling into .
+ ///
+ public override void RenderAttributeValue([NotNull] TagHelperAttributeDescriptor attributeDescriptor,
+ [NotNull] CSharpCodeWriter writer,
+ [NotNull] CodeBuilderContext codeBuilderContext,
+ [NotNull] Action renderAttributeValue)
+ {
+ var propertyType = attributeDescriptor.PropertyInfo.PropertyType;
+
+ if (propertyType.FullName.Equals(_context.ModelExpressionTypeName, StringComparison.Ordinal))
+ {
+ writer.WriteStartMethodInvocation(_context.CreateModelExpressionMethodName)
+ .Write(ModelLambdaVariableName)
+ .Write(" => ")
+ .Write(ModelLambdaVariableName)
+ .Write(".");
+
+ renderAttributeValue(writer);
+
+ writer.WriteEndMethodInvocation(endLine: false);
+ }
+ else
+ {
+ base.RenderAttributeValue(attributeDescriptor, writer, codeBuilderContext, renderAttributeValue);
+ }
+ }
+ }
+}
\ No newline at end of file