Added Medium Trust Support, Razor DLL's can now exist in the GAC or BIN

Added Inline Razor Support - Caches Templates In The App_Data directory for now
Taken out umbdebug from the engine, as it caches the debug content
Custom Build Provider - Future Stub
This commit is contained in:
Elijah
2011-01-20 17:52:56 -10:00
parent 26e6305e9c
commit af79bb24e5
5 changed files with 83 additions and 30 deletions

View File

@@ -9,10 +9,9 @@
</configSections>
<system.web.webPages.razor>
<pages pageBaseType="umbraco.MacroEngines.DynamicNodeContext, umbraco.MacroEngines">
<pages pageBaseType="System.Web.WebPages.WebPage, System.Web.WebPages">
<namespaces>
<add namespace="umbraco"/>
<add namespace="umbraco.MacroEngines"/>
<add namespace="Microsoft.Web.Helpers" />
</namespaces>
</pages>
</system.web.webPages.razor>
@@ -20,8 +19,8 @@
<system.web>
<compilation>
<buildProviders>
<add extension=".cshtml" type="System.Web.WebPages.Razor.RazorBuildProvider, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add extension=".vbhtml" type="System.Web.WebPages.Razor.RazorBuildProvider, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add extension=".cshtml" type="umbraco.MacroEngines.RazorBuildProvider, umbraco.MacroEngines"/>
<add extension=".vbhtml" type="umbraco.MacroEngines.RazorBuildProvider, umbraco.MacroEngines"/>
</buildProviders>
</compilation>
</system.web>

View File

@@ -5,7 +5,7 @@ using umbraco.interfaces;
namespace umbraco.MacroEngines {
public abstract class DynamicNodeContext : WebPageBase, IMacroContext {
public abstract class DynamicNodeContext : WebPage, IMacroContext {
private MacroModel _macro;
private DynamicNode _dynamicNode;

View File

@@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

View File

@@ -0,0 +1,11 @@
namespace umbraco.MacroEngines {
/// <summary>
/// Stub Build Provider If Want To Implement Anything Advanced In The Future
/// Also Allows Us To Register Build Provider In Medium Trust
/// </summary>
public class RazorBuildProvider : System.Web.WebPages.Razor.RazorBuildProvider {
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Web;
using System.Web.Compilation;
using System.Web.WebPages;
@@ -28,44 +28,87 @@ namespace umbraco.MacroEngines
return true;
}
public string GetMd5(string text) {
var x = new System.Security.Cryptography.MD5CryptoServiceProvider();
var bs = System.Text.Encoding.UTF8.GetBytes(text);
bs = x.ComputeHash(bs);
var s = new System.Text.StringBuilder();
foreach (var b in bs) {
s.Append(b.ToString("x2").ToLower());
}
return s.ToString();
}
public string CreateInlineRazorFile(string razorSyntax, string scriptLanguage) {
if (razorSyntax == null)
throw new ArgumentNullException("razorSyntax");
if (scriptLanguage == null)
throw new AbandonedMutexException("scriptLanguage");
var syntaxMd5 = GetMd5(razorSyntax);
var relativePath = "~/App_Data/inlinerazor-" + syntaxMd5 + "." + scriptLanguage;
var physicalPath = IOHelper.MapPath(relativePath);
if (File.Exists(physicalPath)) {
var created = File.GetCreationTime(physicalPath);
if (created <= DateTime.Today.AddMinutes(-10))
File.Delete(physicalPath);
else
return relativePath;
}
using (var file = new StreamWriter(physicalPath)) {
file.Write(razorSyntax);
}
return relativePath;
}
public string ExecuteRazor(MacroModel macro, INode currentPage) {
var context = HttpContext.Current;
var isDebugMode = GlobalSettings.DebugMode && HttpContext.Current.Request.QueryString["umbDebug"] != null;
var sw = new Stopwatch();
if (isDebugMode)
sw.Start();
var contextWrapper = new HttpContextWrapper(context);
var fileLocation = SystemDirectories.Python + "/" + macro.ScriptName;
string fileLocation = null;
if (!string.IsNullOrEmpty(macro.ScriptName)) {
//Razor Is Already Contained In A File
fileLocation = SystemDirectories.Python + "/" + macro.ScriptName;
} else if (!string.IsNullOrEmpty(macro.ScriptCode) && !string.IsNullOrEmpty(macro.ScriptLanguage)) {
//Inline Razor Syntax
fileLocation = CreateInlineRazorFile(macro.ScriptCode, macro.ScriptLanguage);
}
//Returns The Compiled System.Type
if (string.IsNullOrEmpty(fileLocation))
return String.Empty; //No File Location
if (fileLocation.StartsWith("~/") == false)
throw new Exception("Only Relative Paths Are Supported");
var physicalPath = IOHelper.MapPath(fileLocation);
if (File.Exists(physicalPath) == false)
throw new FileNotFoundException(string.Format("Razor Script Not Found At Location, {0}", fileLocation));
//Compile Razor - We Will Leave This To ASP.NET Compilation Engine
//Security in medium trust is strict around here, so we can only pass a relative file path
//ASP.NET Compilation Engine caches returned types
var razorType = BuildManager.GetCompiledType(fileLocation);
if (razorType == null)
throw new ArgumentException("Null Razor Compile Type Returned From The ASP.NET Compilation Engine");
//Instantiates The Razor Script
var razorObj = Activator.CreateInstance(razorType);
var razorWebPage = razorObj as WebPageBase;
if (razorWebPage == null)
throw new InvalidCastException("Razor Template Must Implement System.Web.WebPages.WebPageBase");
throw new InvalidCastException("Razor Context Must Implement System.Web.WebPages.WebPageBase, System.Web.WebPages");
//inject http context - for request response
var httpContext = new HttpContextWrapper(context);
razorWebPage.Context = httpContext;
razorWebPage.Context = contextWrapper;
//inject macro and parameters
//Inject Macro Model And Parameters
if (razorObj is IMacroContext) {
var razorMacro = (IMacroContext)razorObj;
razorMacro.SetMembers(macro, currentPage);
}
//output template
//Output Razor To String
var output = new StringWriter();
if (isDebugMode)
output.Write(string.Format(@"<div title=""Macro Tag: '{0}'"" style=""border: 1px solid #009;""><div style=""border: 1px solid #CCC;"">", macro.Alias));
razorWebPage.ExecutePageHierarchy(new WebPageContext(httpContext, razorWebPage, null), output);
if (isDebugMode) {
sw.Stop();
output.Write(string.Format("<strong>Taken {0}ms<strong>", sw.ElapsedMilliseconds));
output.Write("</div>");
}
razorWebPage.ExecutePageHierarchy(new WebPageContext(contextWrapper, razorWebPage, null), output);
return output.ToString();
}
@@ -73,14 +116,15 @@ namespace umbraco.MacroEngines
try {
return ExecuteRazor(macro, currentPage);
} catch (Exception exception) {
HttpContext.Current.Trace.Write("Macro", string.Format("Error loading Razor Script (file: {0}) {1}", macro.Name, exception.Message));
var loading = string.Format("<div>Error loading Razor Script (file: {0})</br/>", macro.ScriptName);
HttpContext.Current.Trace.Warn("umbracoMacro", string.Format("Error Loading Razor Script (file: {0}) {1} {2}", macro.Name, exception.Message, exception.StackTrace));
var loading = string.Format("<div style=\"border: 1px solid #990000\">Error loading Razor Script {0}</br/>", macro.ScriptName);
if (GlobalSettings.DebugMode)
loading = loading + exception.Message;
loading = loading + "</div>";
return loading;
}
}
#endregion
}
}