From d1fdc22b9b1c6e65ca1b0bb74f0aed3ba5e1735b Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 1 Feb 2016 12:06:29 -0800 Subject: [PATCH] Reduce allocations in FormContext --- .../RenderAtEndOfFormTagHelper.cs | 2 +- .../Rendering/MvcForm.cs | 3 ++- .../Rendering/ViewContext.cs | 23 ++++++++++--------- .../ViewFeatures/DefaultHtmlGenerator.cs | 5 ++-- .../ViewFeatures/FormContext.cs | 20 ++++++++++++---- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/RenderAtEndOfFormTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/RenderAtEndOfFormTagHelper.cs index 3d2f31e245..92870e8320 100644 --- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/RenderAtEndOfFormTagHelper.cs +++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/RenderAtEndOfFormTagHelper.cs @@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers } // Reset the FormContext - ViewContext.FormContext = null; + ViewContext.FormContext = new FormContext(); } } } diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/MvcForm.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/MvcForm.cs index f70ca6b0eb..9e6b2fbfd1 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/MvcForm.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/MvcForm.cs @@ -4,6 +4,7 @@ using System; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Html; +using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Mvc.Rendering @@ -56,7 +57,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering { RenderEndOfFormContent(); _viewContext.Writer.Write(""); - _viewContext.FormContext = null; + _viewContext.FormContext = new FormContext(); } private void RenderEndOfFormContent() diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/ViewContext.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/ViewContext.cs index 76ca759c42..8e7c0e49f3 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/ViewContext.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/ViewContext.cs @@ -15,9 +15,6 @@ namespace Microsoft.AspNetCore.Mvc.Rendering /// public class ViewContext : ActionContext { - // We need a default FormContext if the user uses HTML
instead of an MvcForm - private readonly FormContext _defaultFormContext = new FormContext(); - private FormContext _formContext; private DynamicViewData _viewBag; @@ -84,7 +81,8 @@ namespace Microsoft.AspNetCore.Mvc.Rendering TempData = tempData; Writer = writer; - _formContext = _defaultFormContext; + FormContext = new FormContext(); + ClientValidationEnabled = htmlHelperOptions.ClientValidationEnabled; Html5DateRenderingMode = htmlHelperOptions.Html5DateRenderingMode; ValidationSummaryMessageElement = htmlHelperOptions.ValidationSummaryMessageElement; @@ -125,7 +123,8 @@ namespace Microsoft.AspNetCore.Mvc.Rendering throw new ArgumentNullException(nameof(writer)); } - _formContext = viewContext.FormContext; + FormContext = viewContext.FormContext; + ClientValidationEnabled = viewContext.ClientValidationEnabled; Html5DateRenderingMode = viewContext.Html5DateRenderingMode; ValidationSummaryMessageElement = viewContext.ValidationSummaryMessageElement; @@ -144,14 +143,16 @@ namespace Microsoft.AspNetCore.Mvc.Rendering /// public virtual FormContext FormContext { - get - { - return _formContext; - } + get { return _formContext; } + set { - // Never return a null form context, this is important for validation purposes. - _formContext = value ?? _defaultFormContext; + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + _formContext = value; } } diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/DefaultHtmlGenerator.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/DefaultHtmlGenerator.cs index a6d085e642..29339f13fa 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/DefaultHtmlGenerator.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/DefaultHtmlGenerator.cs @@ -801,8 +801,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures throw new ArgumentNullException(nameof(viewContext)); } - var formContext = viewContext.ClientValidationEnabled ? viewContext.FormContext : null; - if (viewContext.ViewData.ModelState.IsValid && (formContext == null || excludePropertyErrors)) + if (viewContext.ViewData.ModelState.IsValid && (!viewContext.ClientValidationEnabled || excludePropertyErrors)) { // No client side validation/updates return null; @@ -869,7 +868,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures tagBuilder.InnerHtml.AppendHtml(wrappedMessage); tagBuilder.InnerHtml.AppendHtml(htmlSummary); - if (formContext != null && !excludePropertyErrors) + if (viewContext.ClientValidationEnabled && !excludePropertyErrors) { // Inform the client where to replace the list of property errors after validation. tagBuilder.MergeAttribute("data-valmsg-summary", "true"); diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/FormContext.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/FormContext.cs index 63e444c896..2a7460f6fb 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/FormContext.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/FormContext.cs @@ -9,8 +9,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures { public class FormContext { - private readonly Dictionary _renderedFields = - new Dictionary(StringComparer.Ordinal); + private Dictionary _renderedFields; private Dictionary _formData; private IList _endOfFormContent; @@ -52,6 +51,19 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public bool CanRenderAtEndOfForm { get; set; } + private Dictionary RenderedFields + { + get + { + if (_renderedFields == null) + { + _renderedFields = new Dictionary(StringComparer.Ordinal); + } + + return _renderedFields; + } + } + public bool RenderedField(string fieldName) { if (fieldName == null) @@ -60,7 +72,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures } bool result; - _renderedFields.TryGetValue(fieldName, out result); + RenderedFields.TryGetValue(fieldName, out result); return result; } @@ -72,7 +84,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures throw new ArgumentNullException(nameof(fieldName)); } - _renderedFields[fieldName] = value; + RenderedFields[fieldName] = value; } } }