Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Tighten up constraints on Model special case
Browse files Browse the repository at this point in the history
  • Loading branch information
dougbu committed Apr 16, 2016
1 parent 8dac1be commit 25ac089
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ public static ModelExplorer FromLambdaExpression<TModel, TResult>(
var memberExpression = (MemberExpression)expression.Body;
propertyName = memberExpression.Member is PropertyInfo ? memberExpression.Member.Name : null;
if (string.Equals(propertyName, "Model", StringComparison.Ordinal) &&
memberExpression.Type == typeof(TModel))
memberExpression.Type == typeof(TModel) &&
memberExpression.Expression.NodeType == ExpressionType.Constant)
{
// Special case the Model property in RazorPage<TModel>. (m => Model) should behave
// identically to (m => m).
// Special case the Model property in RazorPage<TModel>. (m => Model) should behave identically
// to (m => m). But do the more complicated thing for (m => m.Model) since that is a slightly
// different beast.)
return FromModel(viewData, metadataProvider);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
Expand All @@ -30,8 +31,23 @@ public static TheoryData IdentityExpressions
{ page => page.CreateModelExpression1(), string.Empty },
// m => Model
{ page => page.CreateModelExpression2(), string.Empty },
// m => ViewData.Model (ExpressionHelper can only special-case a leftmost Model node)
{ page => page.CreateModelExpression3(), "ViewData.Model" },
};
}
}

public static TheoryData NotQuiteIdentityExpressions
{
get
{
return new TheoryData<Func<NotQuiteIdentityRazorPage, ModelExpression>, string, Type>
{
// m => m.Model
{ page => page.CreateModelExpression1(), "Model", typeof(RecursiveModel) },
// m => ViewData.Model
{ page => page.CreateModelExpression2(), "ViewData.Model", typeof(RecursiveModel) },
// m => ViewContext.ViewData.Model
// This property has type object because ViewData is not exposed as ViewDataDictionary<TModel>.
{ page => page.CreateModelExpression3(), "ViewContext.ViewData.Model", typeof(object) },
};
}
}
Expand Down Expand Up @@ -93,6 +109,34 @@ public void CreateModelExpression_ReturnsExpectedMetadata_IdentityExpressions(
Assert.Same(modelExplorer, modelExpression.ModelExplorer);
}

[Theory]
[MemberData(nameof(NotQuiteIdentityExpressions))]
public void CreateModelExpression_ReturnsExpectedMetadata_NotQuiteIdentityExpressions(
Func<NotQuiteIdentityRazorPage, ModelExpression> createModelExpression,
string expectedName,
Type expectedType)
{
// Arrange
var viewContext = CreateViewContext();
var viewData = new ViewDataDictionary<RecursiveModel>(viewContext.ViewData);
viewContext.ViewData = viewData;
var modelExplorer = viewData.ModelExplorer;

var page = CreateNotQuiteIdentityPage(viewContext);

// Act
var modelExpression = createModelExpression(page);

// Assert
Assert.NotNull(modelExpression);
Assert.Equal(expectedName, modelExpression.Name);
Assert.NotNull(modelExpression.ModelExplorer);
Assert.NotSame(modelExplorer, modelExpression.ModelExplorer);
Assert.NotNull(modelExpression.Metadata);
Assert.Equal(ModelMetadataKind.Property, modelExpression.Metadata.MetadataKind);
Assert.Equal(expectedType, modelExpression.Metadata.ModelType);
}

[Theory]
[MemberData(nameof(IntExpressions))]
public void CreateModelExpression_ReturnsExpectedMetadata_IntExpressions(
Expand Down Expand Up @@ -142,6 +186,15 @@ private static IdentityRazorPage CreateIdentityPage(ViewContext viewContext)
};
}

public static NotQuiteIdentityRazorPage CreateNotQuiteIdentityPage(ViewContext viewContext)
{
return new NotQuiteIdentityRazorPage
{
ViewContext = viewContext,
ViewData = (ViewDataDictionary<RecursiveModel>)viewContext.ViewData,
};
}

private static TestRazorPage CreatePage(ViewContext viewContext)
{
return new TestRazorPage
Expand Down Expand Up @@ -186,11 +239,29 @@ public ModelExpression CreateModelExpression2()
return CreateModelExpression(m => Model);
}

public ModelExpression CreateModelExpression3()
public override Task ExecuteAsync()
{
throw new NotImplementedException();
}
}

public class NotQuiteIdentityRazorPage : RazorPage<RecursiveModel>
{
public ModelExpression CreateModelExpression1()
{
return CreateModelExpression(m => m.Model);
}

public ModelExpression CreateModelExpression2()
{
return CreateModelExpression(m => ViewData.Model);
}

public ModelExpression CreateModelExpression3()
{
return CreateModelExpression(m => ViewContext.ViewData.Model);
}

public override Task ExecuteAsync()
{
throw new NotImplementedException();
Expand All @@ -205,6 +276,11 @@ public override Task ExecuteAsync()
}
}

public class RecursiveModel
{
public RecursiveModel Model { get; set; }
}

public class RazorPageCreateModelExpressionModel
{
public int Id { get; set; }
Expand Down

0 comments on commit 25ac089

Please sign in to comment.