// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Web.WebPages.Html; namespace System.Web.WebPages { // Class for containing various pieces of data required by a WebPage public class WebPageContext { private static readonly object _sourceFileKey = new object(); private Stack _outputStack; private Stack> _sectionWritersStack; private IDictionary _pageData; private ValidationHelper _validation; private ModelStateDictionary _modelStateDictionary; public WebPageContext() : this(context: null, page: null, model: null) { } public WebPageContext(HttpContextBase context, WebPageRenderingBase page, object model) { HttpContext = context; Page = page; Model = model; } public static WebPageContext Current { get { // The TemplateStack stores instances of WebPageRenderingBase. // Retrieve the top-most item from the stack and cast it to WebPageBase. var httpContext = Web.HttpContext.Current; if (httpContext != null) { var contextWrapper = new HttpContextWrapper(httpContext); var currentTemplate = TemplateStack.GetCurrentTemplate(contextWrapper); var currentPage = (currentTemplate as WebPageRenderingBase); return (currentPage == null) ? null : currentPage.PageContext; } return null; } } internal HttpContextBase HttpContext { get; set; } public object Model { get; internal set; } internal ModelStateDictionary ModelState { get { if (_modelStateDictionary == null) { _modelStateDictionary = new ModelStateDictionary(); } return _modelStateDictionary; } } internal ValidationHelper Validation { get { if (_validation == null) { Debug.Assert(HttpContext != null, "HttpContext must be initalized for Validation to work."); _validation = new ValidationHelper(HttpContext, ModelState); } return _validation; } private set { _validation = value; } } internal Action BodyAction { get; set; } internal Stack OutputStack { get { if (_outputStack == null) { _outputStack = new Stack(); } return _outputStack; } set { _outputStack = value; } } public WebPageRenderingBase Page { get; internal set; } public IDictionary PageData { get { if (_pageData == null) { _pageData = new PageDataDictionary(); } return _pageData; } internal set { _pageData = value; } } internal Stack> SectionWritersStack { get { if (_sectionWritersStack == null) { _sectionWritersStack = new Stack>(); } return _sectionWritersStack; } set { _sectionWritersStack = value; } } // NOTE: We use a hashset because order doesn't matter and we want to eliminate duplicates internal HashSet SourceFiles { get { HashSet sourceFiles = HttpContext.Items[_sourceFileKey] as HashSet; if (sourceFiles == null) { sourceFiles = new HashSet(); HttpContext.Items[_sourceFileKey] = sourceFiles; } return sourceFiles; } } internal static WebPageContext CreateNestedPageContext(WebPageContext parentContext, IDictionary pageData, TModel model, bool isLayoutPage) { var nestedContext = new WebPageContext { HttpContext = parentContext.HttpContext, OutputStack = parentContext.OutputStack, Validation = parentContext.Validation, PageData = pageData, Model = model, }; if (isLayoutPage) { nestedContext.BodyAction = parentContext.BodyAction; nestedContext.SectionWritersStack = parentContext.SectionWritersStack; } return nestedContext; } } }