From f60f14d5377ce9043cd690580444910206f4ce95 Mon Sep 17 00:00:00 2001 From: dougbu Date: Wed, 26 Mar 2014 13:36:39 -0700 Subject: [PATCH] Add `TemplateInfo` property to `ViewDataDictionary` Compared to legacy MVC: - correct usings and namespace - remove `GetFullHtmlFieldId` method; depends on `HtmlHelper` method that can't be static - String -> string - remove reference to a legacy bug - convert internal `VisitedObjects` property to public `AddVisited()` method Further cleanup - remove explicit backing fields for remaining properties - add copy constructor to replace code distributed around legacy MVC - don't "combine and trim" in `GetFullHtmlFieldName()` --- .../View/TemplateInfo.cs | 67 +++++++++++++++++++ .../View/ViewDataDictionary.cs | 4 ++ 2 files changed, 71 insertions(+) create mode 100644 src/Microsoft.AspNet.Mvc.Rendering/View/TemplateInfo.cs diff --git a/src/Microsoft.AspNet.Mvc.Rendering/View/TemplateInfo.cs b/src/Microsoft.AspNet.Mvc.Rendering/View/TemplateInfo.cs new file mode 100644 index 0000000000..3466a9d0db --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Rendering/View/TemplateInfo.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using Microsoft.AspNet.Mvc.ModelBinding; + +namespace Microsoft.AspNet.Mvc.Rendering +{ + public class TemplateInfo + { + // Keep a collection of visited objects to prevent infinite recursion. + private HashSet _visitedObjects; + + public TemplateInfo() + { + FormattedModelValue = string.Empty; + HtmlFieldPrefix = string.Empty; + _visitedObjects = new HashSet(); + } + + public TemplateInfo(TemplateInfo original) + { + FormattedModelValue = original.FormattedModelValue; + HtmlFieldPrefix = original.HtmlFieldPrefix; + _visitedObjects = new HashSet(original._visitedObjects); + } + + public object FormattedModelValue { get; set; } + + public string HtmlFieldPrefix { get; set; } + + public int TemplateDepth + { + get { return _visitedObjects.Count; } + } + + public bool AddVisited(object value) + { + return _visitedObjects.Add(value); + } + + public string GetFullHtmlFieldName(string partialFieldName) + { + if (string.IsNullOrEmpty(partialFieldName)) + { + return HtmlFieldPrefix; + } + else if (string.IsNullOrEmpty(HtmlFieldPrefix)) + { + return partialFieldName; + } + else if (partialFieldName.StartsWith("[", StringComparison.Ordinal)) + { + // The partialFieldName might represent an indexer access, in which case combining + // with a 'dot' would be invalid. + return HtmlFieldPrefix + partialFieldName; + } + else + { + return HtmlFieldPrefix + "." + partialFieldName; + } + } + + public bool Visited(ModelMetadata metadata) + { + return _visitedObjects.Contains(metadata.Model ?? metadata.ModelType); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Rendering/View/ViewDataDictionary.cs b/src/Microsoft.AspNet.Mvc.Rendering/View/ViewDataDictionary.cs index 8de4584369..04571deaf7 100644 --- a/src/Microsoft.AspNet.Mvc.Rendering/View/ViewDataDictionary.cs +++ b/src/Microsoft.AspNet.Mvc.Rendering/View/ViewDataDictionary.cs @@ -21,6 +21,7 @@ namespace Microsoft.AspNet.Mvc.Rendering [NotNull] ModelStateDictionary modelState) { ModelState = modelState; + TemplateInfo = new TemplateInfo(); _data = new Dictionary(StringComparer.OrdinalIgnoreCase); _metadataProvider = metadataProvider; } @@ -41,6 +42,7 @@ namespace Microsoft.AspNet.Mvc.Rendering : this(source.MetadataProvider) { _modelMetadata = source.ModelMetadata; + TemplateInfo = new TemplateInfo(source.TemplateInfo); foreach (var entry in source.ModelState) { @@ -75,6 +77,8 @@ namespace Microsoft.AspNet.Mvc.Rendering } } + public TemplateInfo TemplateInfo { get; private set; } + /// /// Provider for subclasses that need it to override . ///