From 92f3e21fe62ea40342f2eb462ee8a92361ad591b Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Wed, 15 Jul 2015 11:44:26 -0700 Subject: [PATCH] Fix: Metadata ignored for non model-specific EditorTemplate Issue - #2778 --- .../Rendering/Internal/TemplateBuilder.cs | 3 +- .../HtmlGenerationTest.cs | 36 +++++++++++++++++++ .../RazorPageActivatorTest.cs | 4 +-- .../Rendering/DefaultDisplayTemplatesTest.cs | 4 +-- .../Rendering/DefaultEditorTemplatesTest.cs | 4 +-- .../Rendering/DefaultTemplatesUtilities.cs | 1 + .../HtmlGeneration_HomeController.cs | 10 ++++++ .../HtmlGenerationWebSite/Models/Item.cs | 21 +++++++++++ ...temUsingModelSpecificEditorTemplate.cshtml | 3 ++ .../ItemUsingSharedEditorTemplate.cshtml | 5 +++ .../Shared/EditorTemplates/Common.cshtml | 2 ++ .../Shared/EditorTemplates/String.cshtml | 3 ++ 12 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 test/WebSites/HtmlGenerationWebSite/Models/Item.cs create mode 100644 test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/ItemUsingModelSpecificEditorTemplate.cshtml create mode 100644 test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/ItemUsingSharedEditorTemplate.cshtml create mode 100644 test/WebSites/HtmlGenerationWebSite/Views/Shared/EditorTemplates/Common.cshtml create mode 100644 test/WebSites/HtmlGenerationWebSite/Views/Shared/EditorTemplates/String.cshtml diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/Rendering/Internal/TemplateBuilder.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Rendering/Internal/TemplateBuilder.cs index c6d3632546..d2099dc952 100644 --- a/src/Microsoft.AspNet.Mvc.ViewFeatures/Rendering/Internal/TemplateBuilder.cs +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Rendering/Internal/TemplateBuilder.cs @@ -72,7 +72,8 @@ namespace Microsoft.AspNet.Mvc.Rendering.Internal // We need to copy the ModelExplorer to copy the model metadata. Otherwise we might // lose track of the model type/property. Passing null here explicitly, because // this might be a typed VDD, and the model value might not be compatible. - var viewData = new ViewDataDictionary(_viewData, model: null); + // Create VDD of type object so it retains the correct metadata when the model type is not known. + var viewData = new ViewDataDictionary(_viewData, model: null); // We're setting ModelExplorer in order to preserve the model metadata of the original // _viewData even though _model may be null. diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs index 6b00521a4d..c06f3b3723 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs @@ -539,5 +539,41 @@ Products: Laptops (3)"; Assert.Equal(expectedContent.Trim(), responseContent, ignoreLineEndingDifferences: true); #endif } + + [Fact] + public async Task EditorTemplateWithNoModel_RendersWithCorrectMetadata() + { + // Arrange + var server = TestHelper.CreateServer(_app, SiteName, _configureServices); + var client = server.CreateClient(); + var expected = PlatformNormalizer.NormalizeContent( + "" + Environment.NewLine + + "" + Environment.NewLine + Environment.NewLine + + "" + Environment.NewLine + + "" + + Environment.NewLine + Environment.NewLine); + + // Act + var response = await client.GetStringAsync("http://localhost/HtmlGeneration_Home/ItemUsingSharedEditorTemplate"); + + // Assert + Assert.Equal(expected, response); + } + + [Fact] + public async Task EditorTemplateWithSpecificModel_RendersWithCorrectMetadata() + { + // Arrange + var server = TestHelper.CreateServer(_app, SiteName, _configureServices); + var client = server.CreateClient(); + var expected = "" + Environment.NewLine + + "" + Environment.NewLine + Environment.NewLine; + + // Act + var response = await client.GetStringAsync("http://localhost/HtmlGeneration_Home/ItemUsingModelSpecificEditorTemplate"); + + // Assert + Assert.Equal(expected, response); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs index 2a21ad7b7a..05587342dc 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs @@ -112,7 +112,7 @@ namespace Microsoft.AspNet.Mvc.Razor .Returns(serviceProvider.Object); var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor()); - var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()) + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()) { Model = new MyModel() }; @@ -190,7 +190,7 @@ namespace Microsoft.AspNet.Mvc.Razor .Returns(serviceProvider.Object); var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor()); - var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); var viewContext = new ViewContext(actionContext, Mock.Of(), viewData, diff --git a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultDisplayTemplatesTest.cs b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultDisplayTemplatesTest.cs index 0bb39a95f3..68a887c027 100644 --- a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultDisplayTemplatesTest.cs +++ b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultDisplayTemplatesTest.cs @@ -51,7 +51,7 @@ namespace Microsoft.AspNet.Mvc.Core "
HtmlEncode[[Property1]]
" + Environment.NewLine + "
Model = p1, ModelType = System.String, PropertyName = Property1," + " SimpleDisplayText = p1
" + Environment.NewLine - + "
HtmlEncode[[Property2]]
" + Environment.NewLine + + "
HtmlEncode[[Prop2]]
" + Environment.NewLine + "
Model = (null), ModelType = System.String, PropertyName = Property2," + " SimpleDisplayText = (null)
" + Environment.NewLine; @@ -144,7 +144,7 @@ namespace Microsoft.AspNet.Mvc.Core // Arrange var expected = "Model = p1, ModelType = System.String, PropertyName = Property1, SimpleDisplayText = p1" + - "
HtmlEncode[[Property2]]
" + Environment.NewLine + + "
HtmlEncode[[Prop2]]
" + Environment.NewLine + "
Model = (null), ModelType = System.String, PropertyName = Property2," + " SimpleDisplayText = (null)
" + Environment.NewLine; diff --git a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultEditorTemplatesTest.cs b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultEditorTemplatesTest.cs index b849631abe..1a8d5a5c1c 100644 --- a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultEditorTemplatesTest.cs +++ b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultEditorTemplatesTest.cs @@ -97,7 +97,7 @@ namespace Microsoft.AspNet.Mvc.Core " SimpleDisplayText = p1 " + "" + "" + Environment.NewLine - + "
" + Environment.NewLine + + "
" + Environment.NewLine + "
Model = (null), ModelType = System.String, PropertyName = Property2," + " SimpleDisplayText = (null) " + "" + @@ -205,7 +205,7 @@ Environment.NewLine; // Arrange var expected = "Model = p1, ModelType = System.String, PropertyName = Property1, SimpleDisplayText = p1" + - "
" + + "
" + Environment.NewLine + "
" + "Model = (null), ModelType = System.String, PropertyName = Property2, SimpleDisplayText = (null) " + diff --git a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultTemplatesUtilities.cs b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultTemplatesUtilities.cs index 847894f8a1..61f7fcea6a 100644 --- a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultTemplatesUtilities.cs +++ b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/DefaultTemplatesUtilities.cs @@ -30,6 +30,7 @@ namespace Microsoft.AspNet.Mvc.Rendering } public string Property1 { get; set; } + [Display(Name = "Prop2")] public string Property2 { get; set; } public object ComplexInnerModel { get; set; } } diff --git a/test/WebSites/HtmlGenerationWebSite/Controllers/HtmlGeneration_HomeController.cs b/test/WebSites/HtmlGenerationWebSite/Controllers/HtmlGeneration_HomeController.cs index 7ce069c48e..cb2d245258 100644 --- a/test/WebSites/HtmlGenerationWebSite/Controllers/HtmlGeneration_HomeController.cs +++ b/test/WebSites/HtmlGenerationWebSite/Controllers/HtmlGeneration_HomeController.cs @@ -185,5 +185,15 @@ namespace HtmlGenerationWebSite.Controllers { return View(); } + + public IActionResult ItemUsingSharedEditorTemplate() + { + return View(); + } + + public IActionResult ItemUsingModelSpecificEditorTemplate() + { + return View(); + } } } diff --git a/test/WebSites/HtmlGenerationWebSite/Models/Item.cs b/test/WebSites/HtmlGenerationWebSite/Models/Item.cs new file mode 100644 index 0000000000..60de1684c2 --- /dev/null +++ b/test/WebSites/HtmlGenerationWebSite/Models/Item.cs @@ -0,0 +1,21 @@ +// 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.ComponentModel.DataAnnotations; + +namespace HtmlGenerationWebSite.Models +{ + public class Item + { + [UIHint("Common")] + [Display(Name = "ItemName")] + public string Name { get; set; } + + [UIHint("Common")] + [Display(Name = "ItemNo")] + public int Id { get; set; } + + [Display(Name = "ItemDesc")] + public string Description { get; set; } + } +} diff --git a/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/ItemUsingModelSpecificEditorTemplate.cshtml b/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/ItemUsingModelSpecificEditorTemplate.cshtml new file mode 100644 index 0000000000..878b676754 --- /dev/null +++ b/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/ItemUsingModelSpecificEditorTemplate.cshtml @@ -0,0 +1,3 @@ +@using HtmlGenerationWebSite.Models +@model Item +@Html.Editor(nameof(Model.Description)) diff --git a/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/ItemUsingSharedEditorTemplate.cshtml b/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/ItemUsingSharedEditorTemplate.cshtml new file mode 100644 index 0000000000..85de35fa58 --- /dev/null +++ b/test/WebSites/HtmlGenerationWebSite/Views/HtmlGeneration_Home/ItemUsingSharedEditorTemplate.cshtml @@ -0,0 +1,5 @@ +@using HtmlGenerationWebSite.Models +@model Item + +@Html.EditorFor(model => model.Name) +@Html.Editor("Id") diff --git a/test/WebSites/HtmlGenerationWebSite/Views/Shared/EditorTemplates/Common.cshtml b/test/WebSites/HtmlGenerationWebSite/Views/Shared/EditorTemplates/Common.cshtml new file mode 100644 index 0000000000..4e63272013 --- /dev/null +++ b/test/WebSites/HtmlGenerationWebSite/Views/Shared/EditorTemplates/Common.cshtml @@ -0,0 +1,2 @@ +@Html.LabelFor(m => m, new { @class = "control-label col-md-2" }) +@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue) diff --git a/test/WebSites/HtmlGenerationWebSite/Views/Shared/EditorTemplates/String.cshtml b/test/WebSites/HtmlGenerationWebSite/Views/Shared/EditorTemplates/String.cshtml new file mode 100644 index 0000000000..8ea3e6f25c --- /dev/null +++ b/test/WebSites/HtmlGenerationWebSite/Views/Shared/EditorTemplates/String.cshtml @@ -0,0 +1,3 @@ +@model string +@Html.LabelFor(m => m) +@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue)