diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/PartialViewResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/PartialViewResult.cs index 36c06b855c..964c5bd1d4 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/PartialViewResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/PartialViewResult.cs @@ -8,6 +8,7 @@ using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Net.Http.Headers; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc { @@ -59,6 +60,8 @@ namespace Microsoft.AspNet.Mvc var logger = context.HttpContext.RequestServices.GetRequiredService>(); + var options = context.HttpContext.RequestServices.GetRequiredService>(); + var viewName = ViewName ?? context.ActionDescriptor.Name; var viewEngineResult = viewEngine.FindPartialView(context, viewName); if (!viewEngineResult.Success) @@ -80,7 +83,13 @@ namespace Microsoft.AspNet.Mvc using (view as IDisposable) { - await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, ContentType); + await ViewExecutor.ExecuteAsync( + view, + context, + ViewData, + TempData, + options.Options.HtmlHelperOptions, + ContentType); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewExecutor.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewExecutor.cs index 1b0a030efd..966819c2a8 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewExecutor.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewExecutor.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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; @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.Framework.Internal; using Microsoft.Net.Http.Headers; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc { @@ -34,6 +35,7 @@ namespace Microsoft.AspNet.Mvc [NotNull] ActionContext actionContext, [NotNull] ViewDataDictionary viewData, [NotNull] ITempDataDictionary tempData, + [NotNull] HtmlHelperOptions htmlHelperOptions, MediaTypeHeaderValue contentType) { var response = actionContext.HttpContext.Response; @@ -66,9 +68,15 @@ namespace Microsoft.AspNet.Mvc using (var writer = new HttpResponseStreamWriter(response.Body, encoding)) { - var viewContext = new ViewContext(actionContext, view, viewData, tempData, writer); - await view.RenderAsync(viewContext); - } + var viewContext = new ViewContext( + actionContext, + view, + viewData, + tempData, + writer, + htmlHelperOptions); + + await view.RenderAsync(viewContext); } } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs index a29f87bbf0..bd3b61b189 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs @@ -8,6 +8,7 @@ using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; using Microsoft.Framework.Logging; using Microsoft.Net.Http.Headers; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc { @@ -59,6 +60,8 @@ namespace Microsoft.AspNet.Mvc var logger = context.HttpContext.RequestServices.GetRequiredService>(); + var options = context.HttpContext.RequestServices.GetRequiredService>(); + var viewName = ViewName ?? context.ActionDescriptor.Name; var viewEngineResult = viewEngine.FindView(context, viewName); if(!viewEngineResult.Success) @@ -80,7 +83,13 @@ namespace Microsoft.AspNet.Mvc using (view as IDisposable) { - await ViewExecutor.ExecuteAsync(view, context, ViewData, TempData, ContentType); + await ViewExecutor.ExecuteAsync( + view, + context, + ViewData, + TempData, + options.Options.HtmlHelperOptions, + ContentType); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs index 4f831f9d85..6e753cd07a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs @@ -9,6 +9,8 @@ using Microsoft.AspNet.Mvc.Core.Internal; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; using Microsoft.AspNet.Mvc.ModelBinding.Validation; +using Microsoft.AspNet.Mvc.Rendering; +using Microsoft.Framework.Internal; using Newtonsoft.Json; namespace Microsoft.AspNet.Mvc @@ -36,6 +38,7 @@ namespace Microsoft.AspNet.Mvc ModelValidatorProviders = new List(); ClientModelValidatorProviders = new List(); CacheProfiles = new Dictionary(StringComparer.OrdinalIgnoreCase); + HtmlHelperOptions = new HtmlHelperOptions(); SerializerSettings = SerializerSettingsProvider.CreateSerializerSettings(); } @@ -171,5 +174,10 @@ namespace Microsoft.AspNet.Mvc /// /// public IList ModelMetadataDetailsProviders { get; } + + /// + /// Gets or sets programmatic configuration for the HTML helpers and . + /// + public HtmlHelperOptions HtmlHelperOptions { get; [param: NotNull] set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs index 8933de9308..e18b220e96 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs @@ -55,11 +55,11 @@ namespace Microsoft.AspNet.Mvc.Rendering _htmlEncoder = htmlEncoder; // Underscores are fine characters in id's. - IdAttributeDotReplacement = "_"; + IdAttributeDotReplacement = optionsAccessor.Options.HtmlHelperOptions.IdAttributeDotReplacement; } /// - public string IdAttributeDotReplacement { get; set; } + public string IdAttributeDotReplacement { get; } /// public string Encode(string value) diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs index 81271b7b65..e8c4662b84 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs @@ -73,10 +73,6 @@ namespace Microsoft.AspNet.Mvc.Rendering { return _htmlGenerator.IdAttributeDotReplacement; } - set - { - _htmlGenerator.IdAttributeDotReplacement = value; - } } /// @@ -494,7 +490,7 @@ namespace Microsoft.AspNet.Mvc.Rendering var view = viewEngineResult.View; using (view as IDisposable) { - var viewContext = new ViewContext(ViewContext, view, newViewData, TempData, writer); + var viewContext = new ViewContext(ViewContext, view, newViewData, writer); await viewEngineResult.View.RenderAsync(viewContext); } } diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs index f6e3c05fa1..545ac3d4a7 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Mvc.Rendering /// public interface IHtmlGenerator { - string IdAttributeDotReplacement { get; set; } + string IdAttributeDotReplacement { get; } string Encode(string value); diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperOptions.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperOptions.cs new file mode 100644 index 0000000000..626e919107 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperOptions.cs @@ -0,0 +1,44 @@ +// 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. + +namespace Microsoft.AspNet.Mvc.Rendering +{ + /// + /// Provides programmatic configuration for the HTML helpers and . + /// + public class HtmlHelperOptions + { + /// + /// Gets or sets the value. + /// + /// + /// Set this property to to have templated helpers such as + /// and render date and time + /// values as RFC 3339 compliant strings. By default these helpers render dates and times using the current + /// culture. + /// + public Html5DateRenderingMode Html5DateRenderingMode { get; set; } + + /// + /// Gets or sets the that replaces periods in the ID attribute of an element. + /// + public string IdAttributeDotReplacement { get; set; } = "_"; + + /// + /// Gets or sets a value that indicates whether client-side validation is enabled. + /// + public bool ClientValidationEnabled { get; set; } = true; + + /// + /// Gets or sets the element name used to wrap a top-level message generated by + /// and other overloads. + /// + public string ValidationMessageElement { get; set; } = "span"; + + /// + /// Gets or sets the element name used to wrap a top-level message generated by + /// and other overloads. + /// + public string ValidationSummaryMessageElement { get; set; } = "span"; + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs index 3e0bf91b90..47f484c262 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs @@ -24,9 +24,9 @@ namespace Microsoft.AspNet.Mvc.Rendering Html5DateRenderingMode Html5DateRenderingMode { get; set; } /// - /// Gets or sets the character that replaces periods in the ID attribute of an element. + /// Gets the that replaces periods in the ID attribute of an element. /// - string IdAttributeDotReplacement { get; set; } + string IdAttributeDotReplacement { get; } /// /// Gets the metadata provider. Intended for use in extension methods. diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewViewComponentResult.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewViewComponentResult.cs index 6f6594909e..7263eb0cda 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewViewComponentResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewViewComponentResult.cs @@ -96,7 +96,6 @@ namespace Microsoft.AspNet.Mvc context.ViewContext, view, ViewData ?? context.ViewContext.ViewData, - TempData ?? context.ViewContext.TempData, context.Writer); using (view as IDisposable) diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs b/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs index 9ef9432a9d..bb4d5a2734 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs @@ -43,7 +43,8 @@ namespace Microsoft.AspNet.Mvc [NotNull] IView view, [NotNull] ViewDataDictionary viewData, [NotNull] ITempDataDictionary tempData, - [NotNull] TextWriter writer) + [NotNull] TextWriter writer, + [NotNull] HtmlHelperOptions htmlHelperOptions) : base(actionContext) { View = view; @@ -52,9 +53,10 @@ namespace Microsoft.AspNet.Mvc Writer = writer; _formContext = _defaultFormContext; - ClientValidationEnabled = true; - ValidationSummaryMessageElement = "span"; - ValidationMessageElement = "span"; + ClientValidationEnabled = htmlHelperOptions.ClientValidationEnabled; + Html5DateRenderingMode = htmlHelperOptions.Html5DateRenderingMode; + ValidationSummaryMessageElement = htmlHelperOptions.ValidationSummaryMessageElement; + ValidationMessageElement = htmlHelperOptions.ValidationMessageElement; } /// diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/PartialViewResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/PartialViewResultTest.cs index 5230558e1c..54a51f0717 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/PartialViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/PartialViewResultTest.cs @@ -12,6 +12,7 @@ using Microsoft.Framework.Logging; using Microsoft.Net.Http.Headers; using Moq; using Xunit; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc { @@ -167,6 +168,13 @@ namespace Microsoft.AspNet.Mvc .Returns(viewEngine.Object); serviceProvider.Setup(p => p.GetService(typeof(ILogger))) .Returns(new Mock>().Object); + serviceProvider.Setup(s => s.GetService(typeof(IOptions))) + .Returns(() => { + var optionsAccessor = new Mock>(); + optionsAccessor.SetupGet(o => o.Options) + .Returns(new MvcOptions()); + return optionsAccessor.Object; + }); context.HttpContext.RequestServices = serviceProvider.Object; var viewResult = new PartialViewResult @@ -187,6 +195,14 @@ namespace Microsoft.AspNet.Mvc serviceProvider.Setup(s => s.GetService(typeof(ILogger))) .Returns(new Mock>().Object); + serviceProvider.Setup(s => s.GetService(typeof(IOptions))) + .Returns(() => { + var optionsAccessor = new Mock>(); + optionsAccessor.SetupGet(o => o.Options) + .Returns(new MvcOptions()); + return optionsAccessor.Object; + }); + var httpContext = new DefaultHttpContext(); httpContext.RequestServices = serviceProvider.Object; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewExecutorTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewExecutorTest.cs index f03d72a5f0..08957529c5 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewExecutorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewExecutorTest.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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; @@ -75,7 +75,13 @@ namespace Microsoft.AspNet.Mvc var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); // Act - await ViewExecutor.ExecuteAsync(view.Object, actionContext, viewData, null, contentType); + await ViewExecutor.ExecuteAsync( + view.Object, + actionContext, + viewData, + null, + new HtmlHelperOptions(), + contentType); // Assert Assert.Equal(expectedContentType, context.Response.ContentType); @@ -106,7 +112,13 @@ namespace Microsoft.AspNet.Mvc // Act await Record.ExceptionAsync( - () => ViewExecutor.ExecuteAsync(view.Object, actionContext, viewData, null, contentType: null)); + () => ViewExecutor.ExecuteAsync( + view.Object, + actionContext, + viewData, + null, + new HtmlHelperOptions(), + contentType: null)); // Assert Assert.Equal(expectedLength, memoryStream.Length); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewResultTest.cs index ea829c69b4..a9bd283ef2 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/ViewResultTest.cs @@ -9,6 +9,7 @@ using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Routing; using Microsoft.Framework.Logging; +using Microsoft.Framework.OptionsModel; using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -179,6 +180,13 @@ namespace Microsoft.AspNet.Mvc .Returns(viewEngine.Object); serviceProvider.Setup(p => p.GetService(typeof(ILogger))) .Returns(new Mock>().Object); + serviceProvider.Setup(s => s.GetService(typeof(IOptions))) + .Returns(() => { + var optionsAccessor = new Mock>(); + optionsAccessor.SetupGet(o => o.Options) + .Returns(new MvcOptions()); + return optionsAccessor.Object; + }); context.HttpContext.RequestServices = serviceProvider.Object; var viewResult = new ViewResult @@ -199,6 +207,13 @@ namespace Microsoft.AspNet.Mvc serviceProvider.Setup(s => s.GetService(typeof(ILogger))) .Returns(new Mock>().Object); + var optionsAccessor = new Mock>(); + optionsAccessor.SetupGet(o => o.Options) + .Returns(new MvcOptions()); + + serviceProvider.Setup(s => s.GetService(typeof(IOptions))) + .Returns(optionsAccessor.Object); + var httpContext = new DefaultHttpContext(); httpContext.RequestServices = serviceProvider.Object; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs index 3c0fdfab88..624633814b 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs @@ -872,7 +872,6 @@ Environment.NewLine; public string IdAttributeDotReplacement { get { return _innerHelper.IdAttributeDotReplacement; } - set { _innerHelper.IdAttributeDotReplacement = value; } } public IModelMetadataProvider MetadataProvider diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultHtmlGeneratorTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultHtmlGeneratorTest.cs index 201f3d3186..bb7a0d1a95 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultHtmlGeneratorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultHtmlGeneratorTest.cs @@ -612,7 +612,8 @@ namespace Microsoft.AspNet.Mvc.Rendering Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); } public enum RegularEnum diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs index 588f2a7f75..2e52f62b2c 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs @@ -72,7 +72,8 @@ namespace Microsoft.AspNet.Mvc.Rendering CreateViewEngine(), metadataProvider, innerHelperWrapper: null, - htmlGenerator: htmlGenerator); + htmlGenerator: htmlGenerator, + idAttributeDotReplacement: null); } public static HtmlHelper GetHtmlHelper(ViewDataDictionary viewData) @@ -83,7 +84,22 @@ namespace Microsoft.AspNet.Mvc.Rendering CreateViewEngine(), TestModelMetadataProvider.CreateDefaultProvider(), innerHelperWrapper: null, - htmlGenerator: null); + htmlGenerator: null, + idAttributeDotReplacement: null); + } + + public static HtmlHelper GetHtmlHelper( + ViewDataDictionary viewData, + string idAttributeDotReplacement) + { + return GetHtmlHelper( + viewData, + CreateUrlHelper(), + CreateViewEngine(), + TestModelMetadataProvider.CreateDefaultProvider(), + innerHelperWrapper: null, + htmlGenerator: null, + idAttributeDotReplacement: idAttributeDotReplacement); } public static HtmlHelper GetHtmlHelper(TModel model) @@ -91,6 +107,22 @@ namespace Microsoft.AspNet.Mvc.Rendering return GetHtmlHelper(model, CreateViewEngine()); } + public static HtmlHelper GetHtmlHelper(TModel model, string idAttributeDotReplacement) + { + var provider = TestModelMetadataProvider.CreateDefaultProvider(); + var viewData = new ViewDataDictionary(provider); + viewData.Model = model; + + return GetHtmlHelper( + viewData, + CreateUrlHelper(), + CreateViewEngine(), + provider, + innerHelperWrapper: null, + htmlGenerator: null, + idAttributeDotReplacement: idAttributeDotReplacement); + } + public static HtmlHelper> GetHtmlHelperForEnumerable(TModel model) { return GetHtmlHelper>(new TModel[] { model }); @@ -117,7 +149,9 @@ namespace Microsoft.AspNet.Mvc.Rendering return GetHtmlHelper(model, CreateUrlHelper(), CreateViewEngine(), provider); } - public static HtmlHelper GetHtmlHelper(TModel model, ICompositeViewEngine viewEngine) + public static HtmlHelper GetHtmlHelper( + TModel model, + ICompositeViewEngine viewEngine) { return GetHtmlHelper(model, CreateUrlHelper(), viewEngine, TestModelMetadataProvider.CreateDefaultProvider()); } @@ -154,7 +188,14 @@ namespace Microsoft.AspNet.Mvc.Rendering var viewData = new ViewDataDictionary(provider); viewData.Model = model; - return GetHtmlHelper(viewData, urlHelper, viewEngine, provider, innerHelperWrapper, htmlGenerator: null); + return GetHtmlHelper( + viewData, + urlHelper, + viewEngine, + provider, + innerHelperWrapper, + htmlGenerator: null, + idAttributeDotReplacement: null); } private static HtmlHelper GetHtmlHelper( @@ -163,12 +204,17 @@ namespace Microsoft.AspNet.Mvc.Rendering ICompositeViewEngine viewEngine, IModelMetadataProvider provider, Func innerHelperWrapper, - IHtmlGenerator htmlGenerator) + IHtmlGenerator htmlGenerator, + string idAttributeDotReplacement) { var httpContext = new DefaultHttpContext(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var options = new MvcOptions(); + if (!string.IsNullOrEmpty(idAttributeDotReplacement)) + { + options.HtmlHelperOptions.IdAttributeDotReplacement = idAttributeDotReplacement; + } options.ClientModelValidatorProviders.Add(new DataAnnotationsClientModelValidatorProvider()); var optionsAccessor = new Mock>(); optionsAccessor @@ -205,6 +251,7 @@ namespace Microsoft.AspNet.Mvc.Rendering new CommonTestEncoder(), new UrlEncoder(), new JavaScriptStringEncoder()); + if (innerHelperWrapper != null) { innerHelper = innerHelperWrapper(innerHelper); @@ -220,7 +267,15 @@ namespace Microsoft.AspNet.Mvc.Rendering new CommonTestEncoder(), new UrlEncoder(), new JavaScriptStringEncoder()); - var viewContext = new ViewContext(actionContext, Mock.Of(), viewData, null, new StringWriter()); + + var viewContext = new ViewContext( + actionContext, + Mock.Of(), + viewData, + null, + new StringWriter(), + options.HtmlHelperOptions); + htmlHelper.Contextualize(viewContext); return htmlHelper; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperCheckboxTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperCheckboxTest.cs index 6c3e1a9d3b..2c9f3499d8 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperCheckboxTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperCheckboxTest.cs @@ -168,8 +168,9 @@ namespace Microsoft.AspNet.Mvc.Rendering @"Property3=""HtmlEncode[[Property3Value]]"" type=""HtmlEncode[[checkbox]]"" value=""HtmlEncode[[true]]"" />"; var dictionary = new Dictionary { { "Property3", "Property3Value" } }; - var helper = DefaultTemplatesUtilities.GetHtmlHelper(); - helper.IdAttributeDotReplacement = "!!!"; + var helper = DefaultTemplatesUtilities.GetHtmlHelper( + model: null, + idAttributeDotReplacement: "!!!"); helper.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "MyPrefix"; // Act diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperHiddenTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperHiddenTest.cs index d8afa76636..083172fca9 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperHiddenTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperHiddenTest.cs @@ -241,9 +241,10 @@ namespace Microsoft.AspNet.Mvc.Rendering // Arrange var expected = @""; - var helper = DefaultTemplatesUtilities.GetHtmlHelper(GetViewDataWithModelStateAndModelAndViewDataValues()); + var helper = DefaultTemplatesUtilities.GetHtmlHelper( + GetViewDataWithModelStateAndModelAndViewDataValues(), + idAttributeDotReplacement: "$"); helper.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "MyPrefix"; - helper.IdAttributeDotReplacement = "$"; helper.ViewData.ModelState.Clear(); helper.ViewData.ModelState.Add("Property1", GetModelState("modelstate-without-prefix")); helper.ViewData.ModelState.Add("MyPrefix.Property1", GetModelState("modelstate-with-prefix")); @@ -262,9 +263,10 @@ namespace Microsoft.AspNet.Mvc.Rendering // Arrange var expected = @""; - var helper = DefaultTemplatesUtilities.GetHtmlHelper(GetViewDataWithModelStateAndModelAndViewDataValues()); + var helper = DefaultTemplatesUtilities.GetHtmlHelper( + GetViewDataWithModelStateAndModelAndViewDataValues(), + idAttributeDotReplacement: "$"); helper.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "MyPrefix"; - helper.IdAttributeDotReplacement = "$"; helper.ViewData.ModelState.Clear(); helper.ViewData.Clear(); helper.ViewData.Add("Property1", "vdd-without-prefix"); @@ -403,8 +405,7 @@ namespace Microsoft.AspNet.Mvc.Rendering viewData["Property3[height]"] = "Prop3Value"; viewData["Property4.Property5"] = "Prop5Value"; viewData["Property4.Property6[0]"] = "Prop6Value"; - var helper = DefaultTemplatesUtilities.GetHtmlHelper(viewData); - helper.IdAttributeDotReplacement = "$$"; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(viewData, idAttributeDotReplacement: "$$"); var attributes = new Dictionary { { "data-test", "val" } }; // Act @@ -530,10 +531,11 @@ namespace Microsoft.AspNet.Mvc.Rendering // Arrange var expected = @""; - var helper = DefaultTemplatesUtilities.GetHtmlHelper(GetViewDataWithModelStateAndModelAndViewDataValues()); + var helper = DefaultTemplatesUtilities.GetHtmlHelper( + GetViewDataWithModelStateAndModelAndViewDataValues(), + "$"); helper.ViewData.Model.Property1 = "propValue"; helper.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "MyPrefix"; - helper.IdAttributeDotReplacement = "$"; helper.ViewData.ModelState.Clear(); helper.ViewData.ModelState.Add("Property1", GetModelState("modelstate-without-prefix")); helper.ViewData.ModelState.Add("MyPrefix.Property1", GetModelState("modelstate-with-prefix")); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperPasswordTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperPasswordTest.cs index d85410b9df..d393c978c6 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperPasswordTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperPasswordTest.cs @@ -93,9 +93,10 @@ namespace Microsoft.AspNet.Mvc.Rendering // Arrange var expected = @""; - var helper = DefaultTemplatesUtilities.GetHtmlHelper(GetViewDataWithModelStateAndModelAndViewDataValues()); + var helper = DefaultTemplatesUtilities.GetHtmlHelper( + GetViewDataWithModelStateAndModelAndViewDataValues(), + idAttributeDotReplacement: "$"); helper.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "MyPrefix"; - helper.IdAttributeDotReplacement = "$"; // Act var result = helper.Password("Property1", "explicit-value", htmlAttributes: null); @@ -196,8 +197,7 @@ namespace Microsoft.AspNet.Mvc.Rendering { // Arrange var viewData = GetViewDataWithModelStateAndModelAndViewDataValues(); - var helper = DefaultTemplatesUtilities.GetHtmlHelper(viewData); - helper.IdAttributeDotReplacement = "$$"; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(viewData, idAttributeDotReplacement: "$$"); var attributes = new Dictionary { { "data-test", "val" } }; // Act diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewContextTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewContextTests.cs index 8c65b64ac6..8a4b516d8a 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewContextTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/ViewContextTests.cs @@ -12,7 +12,13 @@ namespace Microsoft.AspNet.Mvc.Rendering public void SettingViewData_AlsoUpdatesViewBag() { // Arrange (eventually passing null to these consturctors will throw) - var context = new ViewContext(new ActionContext(null, null, null), view: null, viewData: null, tempData: null, writer: null); + var context = new ViewContext( + new ActionContext(null, null, null), + view: null, + viewData: null, + tempData: null, + writer: null, + htmlHelperOptions: new HtmlHelperOptions()); var originalViewData = context.ViewData = new ViewDataDictionary(metadataProvider: new EmptyModelMetadataProvider()); var replacementViewData = new ViewDataDictionary(metadataProvider: new EmptyModelMetadataProvider()); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/ContentViewComponentResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/ContentViewComponentResultTest.cs index b6388034fa..9d269f722c 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/ContentViewComponentResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/ContentViewComponentResultTest.cs @@ -54,7 +54,13 @@ namespace Microsoft.AspNet.Mvc { var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); - var viewContext = new ViewContext(actionContext, view, viewData, null, TextWriter.Null); + var viewContext = new ViewContext( + actionContext, + view, + viewData, null, + TextWriter.Null, + new HtmlHelperOptions()); + var writer = new StreamWriter(stream) { AutoFlush = true }; var viewComponentDescriptor = new ViewComponentDescriptor() diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/DefaultViewComponentActivatorTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/DefaultViewComponentActivatorTests.cs index 2d28be65f5..7236ed883d 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/DefaultViewComponentActivatorTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/DefaultViewComponentActivatorTests.cs @@ -110,7 +110,8 @@ namespace Microsoft.AspNet.Mvc.ViewComponents Mock.Of(), new ViewDataDictionary(new EmptyModelMetadataProvider()), null, - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); } private class TestViewComponent : ViewComponent diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/JsonViewComponentResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/JsonViewComponentResultTest.cs index 91152914ad..817b7918f6 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/JsonViewComponentResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/JsonViewComponentResultTest.cs @@ -92,7 +92,14 @@ namespace Microsoft.AspNet.Mvc { var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); - var viewContext = new ViewContext(actionContext, view, viewData, null, TextWriter.Null); + var viewContext = new ViewContext( + actionContext, + view, + viewData, + null, + TextWriter.Null, + new HtmlHelperOptions()); + var writer = new StreamWriter(stream) { AutoFlush = true }; var viewComponentDescriptor = new ViewComponentDescriptor() diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/ViewViewComponentResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/ViewViewComponentResultTest.cs index ec3258cef4..9e4f658d69 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/ViewViewComponentResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponents/ViewViewComponentResultTest.cs @@ -300,14 +300,25 @@ namespace Microsoft.AspNet.Mvc private static ViewComponentContext GetViewComponentContext(IView view, ViewDataDictionary viewData) { var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()); - var viewContext = new ViewContext(actionContext, view, viewData, null, TextWriter.Null); + var viewContext = new ViewContext( + actionContext, + view, + viewData, + null, + TextWriter.Null, + new HtmlHelperOptions()); var viewComponentDescriptor = new ViewComponentDescriptor() { Type = typeof(object), }; - var viewComponentContext = new ViewComponentContext(viewComponentDescriptor, new object[0], viewContext, TextWriter.Null); + var viewComponentContext = new ViewComponentContext( + viewComponentDescriptor, + new object[0], + viewContext, + TextWriter.Null); + return viewComponentContext; } } diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlHelperOptionsTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlHelperOptionsTest.cs new file mode 100644 index 0000000000..a031489f10 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlHelperOptionsTest.cs @@ -0,0 +1,87 @@ +// 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.Threading.Tasks; +using Microsoft.AspNet.Builder; +using Microsoft.Framework.DependencyInjection; +using RazorWebSite; +using Xunit; + +namespace Microsoft.AspNet.Mvc.FunctionalTests +{ + public class HtmlHelperOptionsTest + { + private const string SiteName = nameof(RazorWebSite); + private readonly Action _app = new Startup().Configure; + private readonly Action _configureServices = new Startup().ConfigureServices; + + [Fact] + public async Task AppWideDefaultsInViewAndPartialView() + { + // Arrange + var expected = +@"
MySummary +
  • +
+An error occurred. + +
+
+ +
MySummary +
  • +
+An error occurred. + +
+
+ +False"; + + var server = TestHelper.CreateServer(_app, SiteName, _configureServices); + var client = server.CreateClient(); + + // Act + var body = await client.GetStringAsync("http://localhost/HtmlHelperOptions/HtmlHelperOptionsDefaultsInView"); + + // Assert + Assert.Equal(expected, body.Trim()); + } + + [Fact] + public async Task OverrideAppWideDefaultsInViewAndPartialView() + { + // Arrange + var expected = +@"
MySummary +
  • +
+An error occurred. + +
+
+ +True + +
MySummary +
  • +
+An error occurred. + +
+
+ +True"; + + var server = TestHelper.CreateServer(_app, SiteName, _configureServices); + var client = server.CreateClient(); + + // Act + var body = await client.GetStringAsync("http://localhost/HtmlHelperOptions/OverrideAppWideDefaultsInView"); + + // Assert + Assert.Equal(expected, body.Trim()); + } + } +} diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/DefaultTagHelperActivatorTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/DefaultTagHelperActivatorTest.cs index b984fb3ac6..47b02340e2 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/DefaultTagHelperActivatorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/DefaultTagHelperActivatorTest.cs @@ -144,7 +144,8 @@ namespace Microsoft.AspNet.Mvc.Razor Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); return viewContext; } diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs index ce11a8d2ba..16beee3127 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageActivatorTest.cs @@ -44,7 +44,8 @@ namespace Microsoft.AspNet.Mvc.Razor Mock.Of(), new ViewDataDictionary(new EmptyModelMetadataProvider()), Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); // Act activator.Activate(instance, viewContext); @@ -75,7 +76,8 @@ namespace Microsoft.AspNet.Mvc.Razor Mock.Of(), new ViewDataDictionary(new EmptyModelMetadataProvider()), Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); // Act and Assert var ex = Assert.Throws(() => activator.Activate(instance, viewContext)); @@ -117,7 +119,8 @@ namespace Microsoft.AspNet.Mvc.Razor Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); // Act activator.Activate(instance, viewContext); @@ -155,7 +158,8 @@ namespace Microsoft.AspNet.Mvc.Razor Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); // Act activator.Activate(instance, viewContext); @@ -190,7 +194,8 @@ namespace Microsoft.AspNet.Mvc.Razor Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); // Act activator.Activate(instance, viewContext); diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateModelExpressionTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateModelExpressionTest.cs index af586fefc6..f12a7306b4 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateModelExpressionTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateModelExpressionTest.cs @@ -126,7 +126,8 @@ namespace Microsoft.AspNet.Mvc.Razor view: Mock.Of(), viewData: viewData, tempData: Mock.Of(), - writer: new StringWriter()); + writer: new StringWriter(), + htmlHelperOptions: new HtmlHelperOptions()); } private class TestRazorPage : RazorPage diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs index cd81eeec37..e2f8c5c003 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs @@ -124,7 +124,8 @@ namespace Microsoft.AspNet.Mvc.Razor Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); return new TestRazorPage { diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageTest.cs index 40cd4bd50f..a61625ddaa 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageTest.cs @@ -1298,7 +1298,8 @@ namespace Microsoft.AspNet.Mvc.Razor Mock.Of(), null, Mock.Of(), - writer); + writer, + new HtmlHelperOptions()); } private static Action CreateBodyAction(string value) diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs index 797534ab88..713cd3eef8 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs @@ -1339,7 +1339,8 @@ namespace Microsoft.AspNet.Mvc.Razor view, new ViewDataDictionary(new EmptyModelMetadataProvider()), Mock.Of(), - new StringWriter()); + new StringWriter(), + new Rendering.HtmlHelperOptions()); } private static IViewStartProvider CreateViewStartProvider(params IRazorPage[] viewStartPages) diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/CacheTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/CacheTagHelperTest.cs index 1fdf1c347e..58b2f1a0d7 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/CacheTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/CacheTagHelperTest.cs @@ -820,7 +820,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers Mock.Of(), new ViewDataDictionary(new EmptyModelMetadataProvider()), Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); } private static TagHelperContext GetTagHelperContext(string id = "testid", diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/FormTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/FormTagHelperTest.cs index f6dbae13b8..bc909c4509 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/FormTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/FormTagHelperTest.cs @@ -438,7 +438,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers Mock.Of(), new ViewDataDictionary(new TestModelMetadataProvider()), Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ImageTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ImageTagHelperTest.cs index e3298d2854..5b36b8c128 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ImageTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ImageTagHelperTest.cs @@ -206,7 +206,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); return viewContext; } diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/LinkTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/LinkTagHelperTest.cs index 4522db0543..5de1674ed5 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/LinkTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/LinkTagHelperTest.cs @@ -697,7 +697,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); return viewContext; } diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs index c4f97a2728..bd5349a821 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs @@ -792,7 +792,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); return viewContext; } diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TestableHtmlGenerator.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TestableHtmlGenerator.cs index 46be75d6d1..f88a73f1c5 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TestableHtmlGenerator.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TestableHtmlGenerator.cs @@ -63,7 +63,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers Mock.Of(), viewData, Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); return viewContext; } diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ValidationMessageTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ValidationMessageTagHelperTest.cs index 88e320aeaa..bf443495c4 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ValidationMessageTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ValidationMessageTagHelperTest.cs @@ -305,7 +305,8 @@ namespace Microsoft.AspNet.Mvc.TagHelpers new ViewDataDictionary( new EmptyModelMetadataProvider()), Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ValidationSummaryTagHelperTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ValidationSummaryTagHelperTest.cs index 2207e1874e..1b34c79b7c 100644 --- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ValidationSummaryTagHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/ValidationSummaryTagHelperTest.cs @@ -308,7 +308,8 @@ Parameter name: value", new ViewDataDictionary( new EmptyModelMetadataProvider()), Mock.Of(), - TextWriter.Null); + TextWriter.Null, + new HtmlHelperOptions()); } private class Model diff --git a/test/WebSites/ModelBindingWebSite/Controllers/RoundtripController.cs b/test/WebSites/ModelBindingWebSite/Controllers/RoundtripController.cs index 71898031dd..71d988e7ed 100644 --- a/test/WebSites/ModelBindingWebSite/Controllers/RoundtripController.cs +++ b/test/WebSites/ModelBindingWebSite/Controllers/RoundtripController.cs @@ -24,7 +24,13 @@ namespace ModelBindingWebSite.Controllers { _activated = true; var viewData = new ViewDataDictionary(ViewData); - var context = new ViewContext(ActionContext, new TestView(), viewData, null, TextWriter.Null); + var context = new ViewContext( + ActionContext, + new TestView(), + viewData, null, + TextWriter.Null, + new HtmlHelperOptions()); + ((ICanHasViewContext)PersonHelper).Contextualize(context); } diff --git a/test/WebSites/RazorWebSite/Controllers/HtmlHelperOptionsController.cs b/test/WebSites/RazorWebSite/Controllers/HtmlHelperOptionsController.cs new file mode 100644 index 0000000000..de1b13da56 --- /dev/null +++ b/test/WebSites/RazorWebSite/Controllers/HtmlHelperOptionsController.cs @@ -0,0 +1,54 @@ +// 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 Microsoft.AspNet.Mvc; + +namespace RazorWebSite.Controllers +{ + public class HtmlHelperOptionsController : Controller + { + public IActionResult HtmlHelperOptionsDefaultsInView() + { + var model = new DateModel + { + MyDate = new DateTimeOffset( + year: 2000, + month: 1, + day: 2, + hour: 3, + minute: 4, + second: 5, + millisecond: 60, + offset: TimeSpan.FromHours(0)) + }; + + ModelState.AddModelError("Error", "An error occurred."); + return View(model); + } + + public IActionResult OverrideAppWideDefaultsInView() + { + var model = new DateModel + { + MyDate = new DateTimeOffset( + year: 2000, + month: 1, + day: 2, + hour: 3, + minute: 4, + second: 5, + millisecond: 60, + offset: TimeSpan.FromHours(0)) + }; + + ModelState.AddModelError("Error", "An error occurred."); + return View(model); + } + } + + public class DateModel + { + public DateTimeOffset MyDate { get; set; } + } +} diff --git a/test/WebSites/RazorWebSite/Startup.cs b/test/WebSites/RazorWebSite/Startup.cs index 6c92ed0d7b..5400d9aed9 100644 --- a/test/WebSites/RazorWebSite/Startup.cs +++ b/test/WebSites/RazorWebSite/Startup.cs @@ -25,6 +25,14 @@ namespace RazorWebSite options.ViewLocationExpanders.Add(expander); options.ViewLocationExpanders.Add(new CustomPartialDirectoryViewLocationExpander()); }); + services.ConfigureMvc(options => + { + options.HtmlHelperOptions.ClientValidationEnabled = false; + options.HtmlHelperOptions.Html5DateRenderingMode = Microsoft.AspNet.Mvc.Rendering.Html5DateRenderingMode.Rfc3339; + options.HtmlHelperOptions.IdAttributeDotReplacement = "!"; + options.HtmlHelperOptions.ValidationMessageElement = "validationMessageElement"; + options.HtmlHelperOptions.ValidationSummaryMessageElement = "validationSummaryElement"; + }); } public void Configure(IApplicationBuilder app) diff --git a/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/HtmlHelperOptionsDefaultsInPartialView.cshtml b/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/HtmlHelperOptionsDefaultsInPartialView.cshtml new file mode 100644 index 0000000000..fdf768fe8d --- /dev/null +++ b/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/HtmlHelperOptionsDefaultsInPartialView.cshtml @@ -0,0 +1,7 @@ +@model RazorWebSite.Controllers.DateModel + +@Html.ValidationSummary(true, "MySummary") +@Html.ValidationMessage("Error") +@Html.TextBox("Prefix.Property1") +@Html.EditorForModel() +@Html.ViewContext.ClientValidationEnabled \ No newline at end of file diff --git a/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/HtmlHelperOptionsDefaultsInView.cshtml b/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/HtmlHelperOptionsDefaultsInView.cshtml new file mode 100644 index 0000000000..969a2187fb --- /dev/null +++ b/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/HtmlHelperOptionsDefaultsInView.cshtml @@ -0,0 +1,7 @@ +@model RazorWebSite.Controllers.DateModel + +@Html.ValidationSummary(true, "MySummary") +@Html.ValidationMessage("Error") +@Html.TextBox("Prefix.Property1") +@Html.EditorForModel() +@await Html.PartialAsync("HtmlHelperOptionsDefaultsInPartialView", Model) \ No newline at end of file diff --git a/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/OverrideAppWideDefaultsInPartialView.cshtml b/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/OverrideAppWideDefaultsInPartialView.cshtml new file mode 100644 index 0000000000..a2bc55a023 --- /dev/null +++ b/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/OverrideAppWideDefaultsInPartialView.cshtml @@ -0,0 +1,10 @@ +@model RazorWebSite.Controllers.DateModel +@{ + ViewContext.ValidationMessageElement = "ValidationInPartialView"; + ViewContext.ValidationSummaryMessageElement = "ValidationSummaryInPartialView"; +} +@Html.ValidationSummary(true, "MySummary") +@Html.ValidationMessage("Error") +@Html.TextBox("Prefix.Property1") +@Html.EditorForModel() +@Html.ViewContext.ClientValidationEnabled \ No newline at end of file diff --git a/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/OverrideAppWideDefaultsInView.cshtml b/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/OverrideAppWideDefaultsInView.cshtml new file mode 100644 index 0000000000..afc3e885e6 --- /dev/null +++ b/test/WebSites/RazorWebSite/Views/HtmlHelperOptions/OverrideAppWideDefaultsInView.cshtml @@ -0,0 +1,13 @@ +@model RazorWebSite.Controllers.DateModel +@{ + ViewContext.ValidationMessageElement = "ValidationInView"; + ViewContext.ValidationSummaryMessageElement = "ValidationSummaryInView"; + ViewContext.Html5DateRenderingMode = Html5DateRenderingMode.CurrentCulture; + ViewContext.ClientValidationEnabled = true; +} +@Html.ValidationSummary(true, "MySummary") +@Html.ValidationMessage("Error") +@Html.TextBox("Prefix.Property1") +@Html.EditorForModel() +@Html.ViewContext.ClientValidationEnabled +@await Html.PartialAsync("OverrideAppWideDefaultsInPartialView")