DynamicDataRouteHandler.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / DynamicData / DynamicData / DynamicDataRouteHandler.cs / 1305376 / DynamicDataRouteHandler.cs

                            using System.Collections.Generic; 
using System.Diagnostics;
using System.Globalization;
using System.Web.Compilation;
using System.Web.Hosting; 
using System.Web.Routing;
using System.Web.UI; 
 
namespace System.Web.DynamicData {
    ///  
    /// Route handler used for Dynamic Data
    /// 
    public class DynamicDataRouteHandler : IRouteHandler {
 
        private static object s_requestContextKey = new object();
        private static object s_metaTableKey = new object(); 
 
        private object _requestItemsKey = new object();
 
        /// 
        /// ctor
        /// 
        public DynamicDataRouteHandler() { 
            VirtualPathProvider = HostingEnvironment.VirtualPathProvider;
            CreateHandlerCallback = delegate(string s) { 
                return (Page)BuildManager.CreateInstanceFromVirtualPath(s, typeof(Page)); 
            };
        } 

        /// 
        /// The MetaModel that the handler is associated with
        ///  
        public MetaModel Model { get; internal set; }
 
        // the following properties are for mocking purposes 
        internal VirtualPathProvider VirtualPathProvider { get; set; }
        private HttpContextBase _context; 
        internal HttpContextBase HttpContext {
            get {
                return _context ?? new HttpContextWrapper(System.Web.HttpContext.Current);
            } 
            set { _context = value; }
        } 
        internal Func CreateHandlerCallback { get; set; } 

        ///  
        /// Create a handler to process a Dynamic Data request
        /// 
        /// The Route that was matched
        /// The MetaTable found in the route 
        /// The Action found in the route
        ///  
        public virtual IHttpHandler CreateHandler(DynamicDataRoute route, MetaTable table, string action) { 
            // First, get the path to the page (could be custom, shared, or null)
            string virtualPath = GetPageVirtualPath(route, table, action); 

            if (virtualPath != null) {
                // Gets called only for custom pages that we know exist or templates that may or may not
                // exist. This method will throw if virtualPath does not exist, which is fine for templates 
                // but is not fine for custom pages.
                return CreateHandlerCallback(virtualPath); 
            } else { 
                // This should only occur in the event that scaffolding is disabled and the custom page
                // virtual path does not exist. 
                return null;
            }
        }
 
        private string GetPageVirtualPath(DynamicDataRoute route, MetaTable table, string action) {
            long cacheKey = Misc.CombineHashCodes(table, route.ViewName ?? action); 
 
            Dictionary virtualPathCache = GetVirtualPathCache();
 
            string virtualPath;
            if (!virtualPathCache.TryGetValue(cacheKey, out virtualPath)) {
                virtualPath = GetPageVirtualPathNoCache(route, table, action);
                lock (virtualPathCache) { 
                    virtualPathCache[cacheKey] = virtualPath;
                } 
            } 
            return virtualPath;
        } 

        private Dictionary GetVirtualPathCache() {
            var httpContext = HttpContext;
            Dictionary virtualPathCache = (Dictionary)httpContext.Items[_requestItemsKey]; 
            if (virtualPathCache == null) {
                virtualPathCache = new Dictionary(); 
                httpContext.Items[_requestItemsKey] = virtualPathCache; 
            }
            return virtualPathCache; 
        }

        private string GetPageVirtualPathNoCache(DynamicDataRoute route, MetaTable table, string action) {
            // The view name defaults to the action 
            string viewName = route.ViewName ?? action;
 
            // First, get the path to the custom page 
            string customPageVirtualPath = GetCustomPageVirtualPath(table, viewName);
 
            if (VirtualPathProvider.FileExists(customPageVirtualPath)) {
                return customPageVirtualPath;
            } else {
                if (table.Scaffold) { 
                    // If it doesn't exist, try the scaffolded page, but only if scaffolding is enabled on this table
                    return GetScaffoldPageVirtualPath(table, viewName); 
                } else { 
                    // If scaffolding is disabled, null the path so BuildManager doesn't get called.
                    return null; 
                }
            }
        }
 
        /// 
        /// Build the path to a custom page. By default, it looks like ~/DynamicData/CustomPages/[tablename]/[viewname].aspx 
        ///  
        /// The MetaTable that the page is for
        /// The view name 
        /// 
        protected virtual string GetCustomPageVirtualPath(MetaTable table, string viewName) {
            string pathPattern = "{0}CustomPages/{1}/{2}.aspx";
            return String.Format(CultureInfo.InvariantCulture, pathPattern, Model.DynamicDataFolderVirtualPath, table.Name, viewName); 
        }
 
        ///  
        /// Build the path to a page template. By default, it looks like ~/DynamicData/PageTemplates/[tablename]/[viewname].aspx
        ///  
        /// The MetaTable that the page is for
        /// The view name
        /// 
        protected virtual string GetScaffoldPageVirtualPath(MetaTable table, string viewName) { 
            string pathPattern = "{0}PageTemplates/{1}.aspx";
            return String.Format(CultureInfo.InvariantCulture, pathPattern, Model.DynamicDataFolderVirtualPath, viewName); 
        } 

        ///  
        /// Return the RequestContext for this request. A new one is created if needed (can happen if the current request
        /// is not a Dynamic Data request)
        /// 
        /// The current HttpContext 
        /// The RequestContext
        public static RequestContext GetRequestContext(HttpContext httpContext) { 
            if (httpContext == null) { 
                throw new ArgumentNullException("httpContext");
            } 

            return GetRequestContext(new HttpContextWrapper(httpContext));
        }
 
        internal static RequestContext GetRequestContext(HttpContextBase httpContext) {
            Debug.Assert(httpContext != null); 
 
            // Look for the RequestContext in the HttpContext
            var requestContext = httpContext.Items[s_requestContextKey] as RequestContext; 

            // If the current request didn't go through the routing engine (e.g. normal page),
            // there won't be a RequestContext.  If so, create a new one and save it
            if (requestContext == null) { 
                var routeData = new RouteData();
                requestContext = new RequestContext(httpContext, routeData); 
 
                // Add the query string params to the route data.  This allows non routed pages to support filtering.
                DynamicDataRoute.AddQueryStringParamsToRouteData(httpContext, routeData); 

                httpContext.Items[s_requestContextKey] = requestContext;
            }
 
            return requestContext;
        } 
 
        /// 
        /// The MetaTable associated with the current HttpRequest. Can be null for non-Dynamic Data requests. 
        /// 
        /// The current HttpContext
        public static MetaTable GetRequestMetaTable(HttpContext httpContext) {
            if (httpContext == null) { 
                throw new ArgumentNullException("httpContext");
            } 
 
            return GetRequestMetaTable(new HttpContextWrapper(httpContext));
        } 

        internal static MetaTable GetRequestMetaTable(HttpContextBase httpContext) {
            Debug.Assert(httpContext != null);
 
            return (MetaTable)httpContext.Items[s_metaTableKey];
        } 
 
        /// 
        /// Set the MetaTable associated with the current HttpRequest.  Normally, this is set automatically from the 
        /// route, but this method is useful to set the table when used outside of routing.
        /// 
        public static void SetRequestMetaTable(HttpContext httpContext, MetaTable table) {
            SetRequestMetaTable(new HttpContextWrapper(httpContext), table); 
        }
 
        internal static void SetRequestMetaTable(HttpContextBase httpContext, MetaTable table) { 
            Debug.Assert(httpContext != null);
 
            httpContext.Items[s_metaTableKey] = table;
        }

        #region IRouteHandler Members 
        IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) {
            // Save the RequestContext 
            Debug.Assert(requestContext.HttpContext.Items[s_requestContextKey] == null); 
            requestContext.HttpContext.Items[s_requestContextKey] = requestContext;
 
            // Get the dynamic route
            var route = (DynamicDataRoute)requestContext.RouteData.Route;

            // Get the Model from the route 
            MetaModel model = route.Model;
 
            // Get the MetaTable and save it in the HttpContext 
            MetaTable table = route.GetTableFromRouteData(requestContext.RouteData);
            requestContext.HttpContext.Items[s_metaTableKey] = table; 

            // Get the action from the request context
            string action = route.GetActionFromRouteData(requestContext.RouteData);
 
            return CreateHandler(route, table, action);
        } 
        #endregion 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK