/// <summary> /// Output just the scripts for the Agility preview and development bar. /// </summary> /// <param name="helper"></param> public static HtmlString RenderAgilityPreviewBarScripts(this IHtmlHelper helper) { Agility.Web.Objects.AgilityPage p = AgilityContext.Page; if (p != null) { StringBuilder sb = new StringBuilder(); //inject the status panel scripts if (AgilityContext.IsPreview || Current.Settings.DevelopmentMode) { string script = StatusPanelEmitter.GetStatusPanelScriptNoJQuery(); sb.Append(script); } //handle dependencies on ouput cache... if (AgilityContext.OutputCacheKeys.Count > 0) { AgilityCache.AddResponseCacheDependancy(AgilityContext.OutputCacheKeys); } return(new HtmlString(sb.ToString())); } else if (AgilityContext.IsTemplatePreview) { //template preview... string script = StatusPanelEmitter.GetStatusPanelScriptNoJQuery(); return(new HtmlString(script)); } else { return(new HtmlString("")); } }
internal static Type GetTypeFromReflection(string assemblyName, string typeName) { var context = AgilityContext.HttpContext; string typeCacheKey = string.Format("Agility.Web.MVC.RenderContentZone_{0}_{1}", assemblyName, typeName); Type modelType = AgilityCache.Get(typeCacheKey) as Type; if (modelType == null) { lock (_typeLockObject) { modelType = modelType = AgilityCache.Get(typeCacheKey) as Type; if (modelType == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assemblyName == null) { //ignore Agility.Web, and anything from the GAC if (assembly.GlobalAssemblyCache) { continue; } if (assembly.FullName.StartsWith("Agility.Web")) { continue; } } else { if (assembly.FullName.IndexOf(assemblyName, StringComparison.CurrentCultureIgnoreCase) == -1) { continue; } } try { modelType = assembly.GetTypes().FirstOrDefault(type => type.Name.EndsWith(typeName, StringComparison.CurrentCultureIgnoreCase)); if (modelType != null) { AgilityCache.Set(typeCacheKey, modelType, TimeSpan.FromDays(1)); break; } } catch (Exception ex) { //ignore any types we don't have access to load... } } } } } return(modelType); }
public override void ExecuteResult(ActionContext context) { try { EmptyResult empty = new EmptyResult(); //check if the request has been already served (set in route constraint) object constraintCheck = context.HttpContext.Items["Agility.Web.RequestPreviouslyHandledInRouteConstraint"]; if (constraintCheck is bool && ((bool)constraintCheck)) { empty.ExecuteResult(context); return; } HttpRequest Request = context.HttpContext.Request; HttpResponse Response = context.HttpContext.Response; //initialize the offline processing... //HACK: OFFLINE: this should be started in the Startup //if (!OfflineProcessing.IsOfflineThreadRunning) //{ // OfflineProcessing.StartOfflineThread(); //} string url = UriHelper.GetEncodedUrl(Request); string rawUrl = Request.GetEncodedPathAndQuery(); //check if this is Robots.txt and a publishwithagility.com domain (used for staging only) if (( Request.Host.Value.IndexOf(".publishwithagility.com", StringComparison.CurrentCultureIgnoreCase) != -1 || Request.Host.Value.IndexOf(".azurewebsites.net", StringComparison.CurrentCultureIgnoreCase) != -1) && string.Equals(rawUrl, "/robots.txt", StringComparison.CurrentCultureIgnoreCase)) { Response.ContentType = "text/plain"; StringBuilder sb = new StringBuilder(); sb.AppendLine("User-agent: *"); sb.Append("Disallow: /"); var task = Response.WriteAsync(sb.ToString()); task.Wait(); empty.ExecuteResult(context); AgilityCache.TurnOffCacheInProgress(); return; } //don't allow ANY urls to end with / if (!Current.Settings.IgnoreTrailingSlash) { if (rawUrl != "/" && rawUrl.EndsWith("/")) { string newUrl = rawUrl.TrimEnd('/'); AgilityHttpModule.RedirectResponse(newUrl, 301); AgilityCache.TurnOffCacheInProgress(); return; } } if (AgilityContext.BuildAgilityContext()) { empty.ExecuteResult(context); AgilityCache.TurnOffCacheInProgress(); return; } //pre-process the request for any channel or redirections that we encounter... string pagePath = AgilityPagePath; if (!IgnorePrechecks) { if (AgilityHttpModule.HandleChannelsAndRedirects(ref pagePath, LanguageCode)) { empty.ExecuteResult(context); AgilityCache.TurnOffCacheInProgress(); return; } } //use the first page in the sitemap if there is no page passed in... if (string.IsNullOrEmpty(pagePath) || pagePath == "/" || pagePath == "~/") { pagePath = BaseCache.GetDefaultPagePath(AgilityContext.LanguageCode, AgilityContext.WebsiteName, string.Empty); } //check to see if the site should be in "preview mode" if (AgilityHttpModule.CheckPreviewMode(context.HttpContext)) { empty.ExecuteResult(context); AgilityCache.TurnOffCacheInProgress(); return; } AgilityPage page = null; if (!string.IsNullOrEmpty(pagePath)) { //add the ~ if neccessary if (!pagePath.StartsWith("~/")) { if (!pagePath.StartsWith("/")) { pagePath = string.Format("~/{0}", pagePath); } else { pagePath = string.Format("~{0}", pagePath); } } page = Agility.Web.Data.GetPage(pagePath, LanguageCode); //check if this page is a folder, kick out... if (page != null && string.IsNullOrEmpty(page.TemplatePath) && page.TemplateID < 1 && string.IsNullOrEmpty(page.RedirectURL)) { page = null; } } if (AgilityContext.IsResponseEnded) { //check if we've ended the response... empty.ExecuteResult(context); AgilityCache.TurnOffCacheInProgress(); return; } if (page == null) { //possibly route the page if it is a page template... string aspxPath = context.HttpContext.Request.PathBase; int previewIndex = aspxPath.IndexOf("TemplatePreview/", StringComparison.CurrentCultureIgnoreCase); if (previewIndex > -1) { aspxPath = aspxPath.Substring(previewIndex + "TemplatePreview/".Length); aspxPath = string.Format("~/{0}", aspxPath); if (!aspxPath.EndsWith(".aspx", StringComparison.CurrentCultureIgnoreCase)) { //assume we wanted to render a .cshtml file aspxPath = string.Format("{0}.cshtml", aspxPath); } //load the page def in Preview mode... int pageDefinitionID = 0; if (int.TryParse(Request.Query["agilityPageDefinitionID"], out pageDefinitionID) && pageDefinitionID > 0) { AgilityContext.IsTemplatePreview = true; string pageTitle = string.Empty; AgilityContentServer.AgilityPageDefinition _currentPageDefinition = BaseCache.GetPageDefinition(pageDefinitionID, AgilityContext.WebsiteName); if (_currentPageDefinition != null) { AgilityContext.CurrentPageTemplateInPreview = _currentPageDefinition; pageTitle = string.Format("Template Preview - {0}", _currentPageDefinition.Name); ViewData.Model = new AgilityTemplateModel() { Page = new AgilityPage() { Title = pageTitle } }; ViewResult templateView = new ViewResult() { //TODO: handle template preview with inline code... ViewName = _currentPageDefinition.TemplatePath, ViewData = ViewData }; return; } } } // //404 - we can't load the page, so we have to throw a 404 //TODO: figure out how to return a 404 context.HttpContext.Response.StatusCode = 404; return; } //if we get here and we don't have a page, throw a 404 if (page == null) { context.HttpContext.Response.StatusCode = 404; return; } //set the dynamic page formula items from the last ones that were loaded... AgilityContext.DynamicPageFormulaItem = AgilityContext.LastLoadedDynamicPageFormulaItem; //check if this page is a redirect if (!string.IsNullOrEmpty(page.RedirectURL)) { //redirect to the link specified on the page AgilityHttpModule.RedirectResponse(page.RedirectURL); AgilityCache.TurnOffCacheInProgress(); return; } //set the current language and culture based on the language code... AgilityHttpModule.SetLanguageAndCultureBasedOnPage(page); //set the page in context (Context.items) AgilityContext.Page = page; //setup ouput caching AgilityHttpModule.SetupOutputCaching(context.HttpContext.Request, context.HttpContext.Response, page); //assemble the model data ViewData.Model = new AgilityTemplateModel() { Page = page }; ViewData["Title"] = page.Title; string templatePath = string.Empty; DataView dv = Data.GetContentView(AgilityDynamicCodeFile.REFNAME_AgilityPageCodeTemplates, AgilityDynamicCodeFile.LANGUAGECODE_CODE); if (dv != null && dv.Count > 0) { string filter = string.Format("ReferenceName = '{0}' AND Visible = true", page.TemplateID); DataRow[] rows = dv.Table.Select(filter); if (rows.Length > 0) { templatePath = string.Format("~/Views/{0}/DynamicAgilityCode/{1}/{2}.cshtml", rows[0]["VersionID"], AgilityDynamicCodeFile.REFNAME_AgilityPageCodeTemplates, page.TemplateID); } else { } } if (string.IsNullOrEmpty(templatePath)) { //if it's not in code, check the regular template path templatePath = page.TemplatePath; } if (string.IsNullOrEmpty(templatePath)) { //still null? throw an error... throw new ApplicationException("The template for this page is not available."); } //get the view engine var tempdata = HtmlHelperViewExtensions.GetServiceOrFail <ITempDataDictionaryFactory>(context.HttpContext); var engine = HtmlHelperViewExtensions.GetServiceOrFail <IRazorViewEngine>(context.HttpContext); ViewEngineResult viewResult = engine.GetView(null, templatePath, true); var tempDataDict = tempdata.GetTempData(context.HttpContext); StringWriter sw = new StringWriter(); if (!viewResult.Success || viewResult?.View == null) { throw new ApplicationException("The template for this page is not available."); } var viewContext = new ViewContext(context, viewResult.View, ViewData, tempDataDict, sw, new HtmlHelperOptions()); //render the view... var t = viewResult.View.RenderAsync(viewContext); t.Wait(); string s = sw.GetStringBuilder().ToString(); //set the content type Response.ContentType = "text/html"; t = Response.WriteAsync(s); t.Wait(); //ViewResult view = new ViewResult() //{ // ViewName = templatePath, // ViewData = ViewData //}; //view.ExecuteResult(context); } //TODO: do we get an HttpException here? //catch (HttpException hex) //{ // if (hex.InnerException != null) // { // if (hex.InnerException.InnerException != null && hex.InnerException.InnerException is HttpException) // { // //http exceptions thrown from Partial Controllers are buried... // throw hex.InnerException.InnerException; // } // } // throw hex; //} catch (Exception ex) { StringBuilder sb = new StringBuilder(); sb.Append("ViewData: ").AppendLine(); foreach (string key in ViewData.Keys) { sb.AppendFormat("{0}: {1}", key, ViewData[key]).AppendLine(); } ApplicationException aex = new ApplicationException(sb.ToString(), ex); AgilityHttpModule.HandleIntializationException(aex); } }
/// <summary> /// A dictionary of the static routes and page ids from the agility sitemap. /// </summary> public static Dictionary <string, AgilityRouteCacheItem> GetRouteTable(string languageCode, int channelID) { string cacheKey = string.Format("Agility.Web.Providers.AgilitySiteMapProvider.RouteTableCacheKey_{0}_{1}_{2}_{3}", AgilityContext.CurrentMode, languageCode, AgilityContext.WebsiteName, channelID); //get the sitemap first, cause the dependancy is based on that... AgilityContentServer.AgilitySitemap sitemap = BaseCache.GetSitemap(languageCode, AgilityContext.WebsiteName); if (sitemap == null || string.IsNullOrEmpty(sitemap.SitemapXml)) { Agility.Web.Tracing.WebTrace.WriteVerboseLine("Could not load Sitemap data"); return(new Dictionary <string, AgilityRouteCacheItem>()); } Dictionary <string, AgilityRouteCacheItem> routeTable = AgilityCache.Get(cacheKey) as Dictionary <string, AgilityRouteCacheItem>; if (routeTable != null) { return(routeTable); } lock (_lockObj) { Agility.Web.Tracing.WebTrace.WriteVerboseLine(string.Format("Building route table - {0} - {1}", languageCode, channelID)); //check to see if this has been added to cache while we've been waiting... routeTable = AgilityCache.Get(cacheKey) as Dictionary <string, AgilityRouteCacheItem>; if (routeTable != null) { return(routeTable); } routeTable = new Dictionary <string, AgilityRouteCacheItem>(); //get the sitemap xml that we need for the sitemap... XmlDocument document = new XmlDocument(); document.LoadXml(sitemap.SitemapXml); XmlNodeList siteMapNodes = document.SelectNodes(string.Format("//SiteNode[@channelID='{0}']", channelID)); if (siteMapNodes.Count == 0) { //if the channels haven't been synced yet... siteMapNodes = document.SelectNodes("//SiteNode"); } foreach (XmlNode node in siteMapNodes) { XmlElement elem = node as XmlElement; if (elem == null) { continue; } //add to the route table if this node represents a page... int pageID = -1; if (int.TryParse(elem.GetAttribute("picID"), out pageID) && pageID > 0) { string path = GetRoutePath(elem); if (!routeTable.ContainsKey(path)) { AgilityRouteCacheItem item = new AgilityRouteCacheItem() { PageID = pageID }; if (!string.IsNullOrEmpty(elem.GetAttribute("dynamicPageContentReferenceName")) || !string.IsNullOrEmpty(elem.GetAttribute("dynamicPageParentFieldName"))) { //update the parent item... XmlElement parentElem = elem.ParentNode as XmlElement; if (parentElem != null) { string parentPath = GetRoutePath(parentElem); if (routeTable.ContainsKey(parentPath)) { routeTable[parentPath].ChildDynamicPagePath = path; } } } routeTable[path] = item; } } } //always put the thing in cache... //make it dependant of the sitemap file (this way we can cache in live and staging mode...) CacheDependency dep = null; if (AgilityContext.ContentAccessor != null && AgilityContext.CurrentMode == Enum.Mode.Live) { AgilityItemKey itemKey = new AgilityItemKey(); itemKey.Key = BaseCache.ITEMKEY_SITEMAP; itemKey.LanguageCode = languageCode; itemKey.ItemType = typeof(AgilitySitemap).Name; string sitemapCacheKey = BaseCache.GetCacheKey(itemKey); dep = new CacheDependency(new string[0], new string[1] { sitemapCacheKey }); } else { string filename = BaseCache.GetFilePathForItem(sitemap, AgilityContext.WebsiteName, transientPath: true); bool exists = File.Exists(filename); dep = new CacheDependency(filename); } AgilityCache.Set(cacheKey, routeTable, TimeSpan.FromDays(1), dep, AgilityContext.DefaultCachePriority); return(routeTable); } }
public async Task <HtmlString> InvokeAsync() { AgilityContext.HttpContext = HttpContext; StringBuilder sb = new StringBuilder(); Agility.Web.Objects.AgilityPage p = AgilityContext.Page; if (p != null) { //inject the status panel scripts if (AgilityContext.IsPreview || Current.Settings.DevelopmentMode) { string script = StatusPanelEmitter.GetStatusPanelScriptNoJQuery(); sb.AppendLine(script); } if (!string.IsNullOrEmpty(p.CustomAnalyticsScript)) { string script = p.CustomAnalyticsScript; if (script.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR) != -1) { string scriptBottomPage = script.Substring(script.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR) + AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR.Length); if (!string.IsNullOrEmpty(scriptBottomPage)) { sb.AppendLine(scriptBottomPage); } } } //add the Javascript tracking stuff if (p.IncludeInStatsTracking) { //global script if (!string.IsNullOrEmpty(AgilityContext.Domain.StatsTrackingScript)) { string scriptTopGlobal = AgilityContext.Domain.StatsTrackingScript; if (scriptTopGlobal.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR) != -1) { string scriptBottomGlobal = scriptTopGlobal.Substring(scriptTopGlobal.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR) + AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR.Length); if (!string.IsNullOrEmpty(scriptBottomGlobal)) { sb.AppendLine(scriptBottomGlobal); } } } } //handle dependencies on ouput cache... if (AgilityContext.OutputCacheKeys.Count > 0) { AgilityCache.AddResponseCacheDependancy(AgilityContext.OutputCacheKeys); } } else if (AgilityContext.IsTemplatePreview) { //template preview... string script = StatusPanelEmitter.GetStatusPanelScriptNoJQuery(); sb.AppendLine(script); } return(new HtmlString(sb.ToString())); }