Assembly: EPiServer (in EPiServer.dll) Version: 6.0.530.0
Syntax
| C# |
|---|
public class Global : SiteBase |
Remarks
The global.asax.cs file on an EPiServer site should inherit from Global. This is a requirement for the site to work.
#region Copyright � 1997-2008 EPiServer AB. All Rights Reserved. /* This code may only be used according to the EPiServer License Agreement. The use of this code outside the EPiServer environment, in whole or in parts, is forbidden without prior written permission from EPiServer AB. EPiServer is a registered trademark of EPiServer AB. For more information see http://www.episerver.com/license or request a copy of the EPiServer License Agreement by sending an email to info@episerver.com*/ #endregion using System; using System.Diagnostics; using System.IO; using System.Net; using System.Web; using EPiServer.Configuration; using EPiServer.Core; using EPiServer.Security; using EPiServer.Web; using EPiServer.Web.Hosting; using log4net; namespace EPiServer { /// <summary> /// <img src="Icons/CSharp.gif" alt="Source included" /> /// Base class for global.asax that supports EPiServer-specific features. /// </summary> /// <remarks> /// <para> /// The global.asax.cs file on an EPiServer site should inherit from <see cref="EPiServer.Global" />. /// This is a requirement for the site to work. /// </para> /// <code source="../EPiServerNET/GlobalBase.cs" lang="cs"/> /// </remarks> /// <example> /// The following code example demonstrates the usage of <b>Global</b> to read the BaseDiretory. /// <code> /// BaseDirectory: /// <![CDATA[<%= EPiServer.Global.BaseDirectory %>]]> /// </code> /// </example> public partial class Global : SiteBase { // If the custom string that specifies which cached response is used to respond // to the current request is equal with VaryByCustomKey then the requsets path will be returned. private const string VaryByCustomKey = "path"; // Base folder for the application - used to locate related files. private static string _baseDirectory; // The Application ID of the IIS instance that we are running under private static string _instanceName; // Resolves a host name or IP address to an System.Net.IPHostEntry instance private static IPHostEntry _localHost; // The current provider for Url rewrite functionality private static UrlRewriteProvider _urlRewriteProvider; // The static logger object private static readonly ILog _log = LogManager.GetLogger(typeof(Global)); /// <summary> /// Initializes a new instance of the <see cref="Global"/> class. /// </summary> public Global() { _log.Debug("EPiServer.Global ctor"); EPiServer.Framework.Initialization.InitializationModule.FrameworkInitialization(EPiServer.Framework.Initialization.HostType.WebApplication); _log.Debug("EPiServer.Global Initialization done"); } #region Static properties /// <summary> /// Global instance of language information /// </summary> /// <remarks> /// <para> /// The main use for the <b>EPLang</b> property is to translate EPiServer strings into the /// current language. <b>EPLang</b> is an instantce of <see cref="EPiServer.Core.LanguageManager"/>, /// which has a property, <b>Directory</b>, and a few methods. It is the Translate method that is /// primarily used. /// </para> /// By default, EPiServer will monitor the <b>BaseDirectory</b> + "/lang" directory for language files. /// <para> /// <b>Translate</b> has two overloaded variants. The first one is used in the first two code examples below. /// It takes a string argument, key, in a simplified XML XPath form and returns the proper language string. /// The key is typically something like "/admin/settings/heading", where the expression closely follows /// the folder/ file/ usage pattern. You can also enter "#" to automatically construct a path to the current /// file. For example, calling the <b>Translate</b> method in the file /templates/mypage.aspx with the key set to /// '#heading', Translate( "#heading" ) is equivalent to Translate( "/templates/mypage/heading"). /// </para> /// <para> /// <note> /// <b>Note:</b> If the key does not begin with a "/" or "#", the key itself is simply returned as the result. /// The reason for this behavior is to be able to use EPiServer Web controls that use Translate for visible /// strings, but you might not have translations in place or you prefer not to translate the text. /// </note> /// </para> /// <para> /// The second form of <b>Translate</b> takes two string arguments, the first again being a key used in the /// same way as earlier, and the second argument being a language identifier. /// </para> /// <para> /// </para> /// </remarks> [Obsolete("Use LanguageManager.Instance instead.")] public static LanguageManager EPLang { get { return LanguageManager.Instance; } set { } } /// <summary> /// Global instance of data factory /// </summary> [Obsolete("Use DataFactory.Instance instead.")] public static DataFactory EPDataFactory { get { return DataFactory.Instance; } } /// <summary> /// Gets or sets the URL rewrite provider. /// </summary> /// <value> /// Instance of the URLRewriteProvider <see cref="T:EPiServer.Web.UrlRewriteProvider"/> Type /// </value> /// <remarks> /// Initial configuration of the UrlRewriteProvider is done from the Initialize method on <see cref="T:EPiServer.Web.InitializationModule"/>. I e if running /// outside of a web server you must first call the INitialize method before you can read a valid value from this property. /// </remarks> public static UrlRewriteProvider UrlRewriteProvider { get { return _urlRewriteProvider; } set { _urlRewriteProvider = value; } } /// <summary> /// The physical root directory where the site is installed, e.g. "D:/INetpub/WWWRoot/Example/", /// when using Internet Information Services (IIS) folder. /// </summary> /// <remarks> /// <b>Note:</b> Slashes are used instead of backslashes. /// </remarks> public static string BaseDirectory { get { if (_baseDirectory == null) { _baseDirectory = AppDomain.CurrentDomain.BaseDirectory; // Make sure that base directory has a trailing backslash since existing code assumes this. if (!_baseDirectory.EndsWith("/") && !_baseDirectory.EndsWith("\\")) { _baseDirectory += "\\"; } } return _baseDirectory; } set { _baseDirectory = value; } } /// <summary> /// IIS Metabase key path for the application, e.g. "_LM_W3SVC_1_ROOT_Example". /// </summary> /// <remarks> /// <note> /// <b>Note:</b> Underscore is used instead of slash. /// </note> /// </remarks> public static string InstanceName { get { if (_instanceName == null) { _instanceName = GenericHostingEnvironment.ApplicationID; if (_instanceName != null) { _instanceName = _instanceName.Replace("/", "_"); } } return _instanceName == null ? "_Total" : _instanceName; } set { _instanceName = value; } } #endregion /// <summary> /// Provides an application-wide implementation of the <see cref="P:System.Web.UI.PartialCachingAttribute.VaryByCustom"/> property. /// </summary> /// <param name="context">An <see cref="T:System.Web.HttpContext"/> object that contains information about the current Web request.</param> /// <param name="custom">The custom string that specifies which cached response is used to respond to the current request.</param> /// <returns> /// If the value of the <paramref name="custom"/> parameter is "path", the requsets path will be returned. /// If the value of the <paramref name="custom"/> parameter is "browser", the browser's <see cref="P:System.Web.Configuration.HttpCapabilitiesBase.Type"/>; otherwise, null. /// </returns> public override string GetVaryByCustomString(HttpContext context, string custom) { if (String.Equals(custom, VaryByCustomKey, StringComparison.OrdinalIgnoreCase)) { Url requestUrl = new Url(context.Request.RawUrl); return requestUrl.Path; } return base.GetVaryByCustomString(context, custom); } /// <summary> /// This Init method is called AFTER Application_Start and AFTER the Init methot on HttpModules /// Executes custom initialization code after all event handler modules have been added. /// </summary> /// <remarks> /// Note! You cannot count on HttpContext being available - i e do NOT attempt to access it. /// </remarks> public override void Init() { _log.Debug("EPiServer.Global.Init Enter"); // Occurs when an unhandled exception is thrown. Error += new EventHandler(Global_Error); // Occurs when a security module has established the identity of the user. AuthenticateRequest += new EventHandler(Global_AuthenticateRequest); // If we will replace the current principal with a VirtualRolePrincipal if (VirtualRoles.IsReplacePrincipal) { PostAuthenticateRequest += new EventHandler(VirtualRolePrincipal.VirtualRolePrincipal_PostAuthenticateRequest); // ASP.NET 3.5 handles the role caching correctly, but cannot understand the VirtualRolePrincipal, therefore // we have to use our implementation when we wrap the principal with our VirtualRolePrincipal. if (System.Web.Security.Roles.Enabled && System.Web.Security.Roles.CacheRolesInCookie) { EndRequest += new EventHandler(VirtualRolePrincipal.VirtualRolePrincipal_EndRequest); } } // Occurs just before ASP.NET starts executing an event handler PreRequestHandlerExecute += new EventHandler(Global_PreRequestHandlerExecute); _log.Debug("EPiServer.Global.Init Leave"); } /// <summary> /// Code to emulate IIS handling of folders / default documents. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <remarks> /// Verify if this code is really needed when running under IIS7 - it could most likely be disabled then... /// </remarks> private void Global_AuthenticateRequest(object sender, EventArgs e) { // Emulate IIS directory redirection and default document handling. string path = Request.Url.AbsolutePath; // If we're referring to a directory but no document, try to find an existing default document. if (path.EndsWith("/")) { // Get an array of possible choices for default documents. string[] defaultDocuments = GetDefaultDocuments(Request.Url); if (defaultDocuments != null) { foreach (string defaultDocument in defaultDocuments) { UrlBuilder defaultUrl = new UrlBuilder(Request.Url); defaultUrl.Path += defaultDocument; // If this path actually exists... if (GenericHostingEnvironment.VirtualPathProvider.FileExists(defaultUrl.Path)) { // ....rewrite the path to refer to this default document, and serve it up HttpContext.Current.RewritePath(defaultUrl.Path + defaultUrl.Query); break; } } } return; } // Request URL does not end with a slash, check if we have a corresponding directory if (GenericHostingEnvironment.VirtualPathProvider.DirectoryExists(path)) { // TODO - check if this may be a problem - redirecting with host name? // if we're referring to an existing directory, add a "/" and redirect path += "/"; // NOTE! Since we are changing the nesting level of the request, we must do a redirect to ensure // that the browser requesting the information is in sync with regards to the base URL. Response.Redirect(path); } } /// <summary> /// EPiServer support for restricting access to the UI folder and for precompiling .aspx files. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <remarks> /// The "precompile" feature is really obsolete as of ASP.NET 2.0, but is retained for backwards compatibility. /// </remarks> protected virtual void Global_PreRequestHandlerExecute(Object sender, EventArgs e) { if (Request == null) { return; } // Build the arguments for, and raise the ValidateRequestAccess event. This gives the chance to stop // processing a request if it attempts to access the UI through an unwanted channel, for example // originating from the wrong IP-subnet, through the wrong host etc. // This is just a convenience, it can be done by simply attaching to almost any of the HttpHandler requests. ValidateRequestAccessEventArgs validateRequestEventArgs = new ValidateRequestAccessEventArgs(Request); OnValidateRequestAccess(validateRequestEventArgs); if (validateRequestEventArgs.Cancel) { Response.Clear(); ExceptionManager.RenderHttpRuntimeError(new HttpException(404, "Not Found")); Response.End(); } if (Request.QueryString["EP_PreCompile"] == null) { return; } _log.Info("1.2.7 Precompilation request for file " + Request.RawUrl); Response.End(); } /// <summary> /// Handles the Error event of the Global control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="evt">The <see cref="System.EventArgs"/> instance containing the event data.</param> private void Global_Error(object sender, EventArgs evt) { if (HttpContext.Current == null) { return; } Exception e; try { //Get the previous exception e = Server.GetLastError(); } catch { return; } _log.Error("1.2.5 Unhandled exception in ASP.NET", e); // Try to get the InconsistentDataException instance that caused the current exception InconsistentDataException inconsistent = e.InnerException as InconsistentDataException; if (inconsistent != null) { // The rare case where a delayed long string load fails to retrieve the correct data. Clear cache for // the relevant page to avoid that this error happens again for the same page. CacheManager.Remove("EPPageData:" + new PageReference(inconsistent.PageLink.ID, EPiServer.Configuration.Settings.Instance.Parent.SiteId).ToString()); } if (!EnableGlobalErrorHandling) { return; } if (HttpContext.Current.Items.Contains("EPHandledUnhandledException")) { return; } try { // Clears the previous exception Server.ClearError(); HttpContext.Current.Items.Add("EPHandledUnhandledException", true); //Clears all content output from the buffer stream Response.Clear(); //Renders an error message to the user based on the exception ExceptionManager.RenderHttpRuntimeError(e); Response.End(); } catch { } } /// <summary> /// Gets a value indicating whether show error message. /// </summary> /// <value> /// <c>true</c> If the GlobalErrorHandling flag is "on" or if it sets to "remoteonly" and the request is not locally; otherwise is <c>false</c>. /// </value> private bool EnableGlobalErrorHandling { get { // Read error handling option ["RemoteOnly", "On","Off"] string errHandling = Settings.Instance.GlobalErrorHandling; // Empty string consider as off if (String.IsNullOrEmpty(errHandling)) { errHandling = "off"; } else { errHandling = errHandling.ToLowerInvariant(); } // True if the error handling is on or (if it sets remoteonly and the request is not from local client) return (errHandling == "on" || (errHandling == "remoteonly" && !IsRequestLocal)); } } /// <summary> /// Gets a value indicating whether the IP host address of the client is local. /// </summary> /// <value> /// <c>true</c> if IP host address of the remote client is local; otherwise, <c>false</c>. /// </value> private bool IsRequestLocal { get { try { if (_localHost == null) { _localHost = Dns.GetHostEntry(Dns.GetHostName()); } //Converts an IP address string to an System.Net.IPAddress. System.Net.IPAddress remoteAddress = System.Net.IPAddress.Parse(HttpContext.Current.Request.UserHostAddress); return remoteAddress.Equals(System.Net.IPAddress.Loopback) || remoteAddress.Equals(System.Net.IPAddress.IPv6Loopback) || Array.IndexOf(_localHost.AddressList, remoteAddress) >= 0; } catch { // If there are some errors as result of the IsLocal calculation, treat it as if the request is not local, just to be on the safe side... } return false; } } } }
Examples
The following code example demonstrates the usage of Global to read the BaseDiretory.
CopyC#
BaseDirectory: <%= EPiServer.Global.BaseDirectory %>