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 . ///