Merge pull request #7301 from aspnet/release/2.1

PartialTagHelper should not fallback to the current page's model if a…
This commit is contained in:
Pranav K 2018-01-25 11:07:23 -08:00 committed by GitHub
commit 5f2f65e903
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 1 deletions

View File

@ -101,7 +101,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var view = viewEngineResult.View;
// Determine which ViewData we should use to construct a new ViewData
var baseViewData = ViewData ?? ViewContext.ViewData;
var model = For?.Model ?? ViewContext.ViewData.Model;
// Use the rendering View's model only if an asp-for expression does not exist
var model = For != null ? For.Model : ViewContext.ViewData.Model;
var newViewData = new ViewDataDictionary<object>(baseViewData, model);
var partialViewContext = new ViewContext(ViewContext, view, newViewData, writer);

View File

@ -67,6 +67,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
// Testing InputTagHelpers invoked in the partial views
{ "ProductList", "/HtmlGeneration_Product" },
{ "ProductListUsingTagHelpers", "/HtmlGeneration_Product" },
{ "ProductListUsingTagHelpersWithNullModel", "/HtmlGeneration_Product" },
// Testing the ScriptTagHelper
{ "Script", null },
};

View File

@ -0,0 +1,30 @@
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<form action="/HtmlGeneration_Product" method="post">
<div>
<label class="product" for="z0__HomePage">HomePage</label>
<input type="url" size="50" disabled="disabled" readonly="readonly" id="z0__HomePage" name="[0].HomePage" value="" />
</div>
<div>
<label class="product" for="z0__Number">Number</label>
<input type="number" data-val="true" data-val-required="The Number field is required." id="z0__Number" name="[0].Number" value="" />
</div>
<div>
<label class="product" for="z0__ProductName">ProductName</label>
<input type="text" data-val="true" data-val-required="The ProductName field is required." id="z0__ProductName" name="[0].ProductName" value="" />
</div>
<div>
<label class="product" for="z0__Description">Description</label>
<textarea rows="4" cols="50" class="product" id="z0__Description" name="[0].Description">
</textarea>
</div>
<div>HtmlFieldPrefix = </div>
<input type="submit" />
<input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
</body>
</html>

View File

@ -233,6 +233,52 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
view.Verify();
}
[Fact]
public async Task ProcessAsync_DoesNotUseModelFromViewdata_IfModelExpressionEvalulatesToNull()
{
// Arrange
var bufferScope = new TestViewBufferScope();
var partialName = "_Partial";
var modelMetadataProvider = new TestModelMetadataProvider();
var containerModel = new TestModel { Property = null };
var containerModelExplorer = modelMetadataProvider.GetModelExplorerForType(
typeof(TestModel),
containerModel);
var propertyModelExplorer = containerModelExplorer.GetExplorerForProperty(nameof(TestModel.Property));
var modelExpression = new ModelExpression("Property", propertyModelExplorer);
var viewContext = GetViewContext();
viewContext.ViewData.Model = new object();
var view = new Mock<IView>();
view.Setup(v => v.RenderAsync(It.IsAny<ViewContext>()))
.Callback((ViewContext v) =>
{
Assert.Null(v.ViewData.Model);
})
.Returns(Task.CompletedTask)
.Verifiable();
var viewEngine = new Mock<ICompositeViewEngine>();
viewEngine.Setup(v => v.GetView(It.IsAny<string>(), partialName, false))
.Returns(ViewEngineResult.Found(partialName, view.Object));
var tagHelper = new PartialTagHelper(viewEngine.Object, bufferScope)
{
Name = partialName,
ViewContext = viewContext,
For = modelExpression,
};
var tagHelperContext = GetTagHelperContext();
var output = GetTagHelperOutput();
// Act
await tagHelper.ProcessAsync(tagHelperContext, output);
// Assert
view.Verify();
}
[Fact]
public async Task ProcessAsync_SetsHtmlFieldPrefix_UsingModelExpression()
{

View File

@ -110,6 +110,16 @@ namespace HtmlGenerationWebSite.Controllers
public IActionResult ProductListUsingTagHelpers() => View(_products);
public IActionResult ProductListUsingTagHelpersWithNullModel()
{
var model = new List<Product>
{
null,
};
return View(nameof(ProductListUsingTagHelpers), model);
}
public IActionResult EmployeeList()
{
var employees = new List<Employee>