diff --git a/umbraco.MacroEngines.Juno/Web.config b/umbraco.MacroEngines.Juno/App.Config
similarity index 64%
rename from umbraco.MacroEngines.Juno/Web.config
rename to umbraco.MacroEngines.Juno/App.Config
index bcfb6a61bc..dd0f2da6a3 100644
--- a/umbraco.MacroEngines.Juno/Web.config
+++ b/umbraco.MacroEngines.Juno/App.Config
@@ -9,10 +9,9 @@
-
+
-
-
+
@@ -20,8 +19,8 @@
-
-
+
+
diff --git a/umbraco.MacroEngines.Juno/DynamicNodeContext.cs b/umbraco.MacroEngines.Juno/DynamicNodeContext.cs
index 211fa8521e..23094807f0 100644
--- a/umbraco.MacroEngines.Juno/DynamicNodeContext.cs
+++ b/umbraco.MacroEngines.Juno/DynamicNodeContext.cs
@@ -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;
diff --git a/umbraco.MacroEngines.Juno/Properties/AssemblyInfo.cs b/umbraco.MacroEngines.Juno/Properties/AssemblyInfo.cs
index 142b376615..27cda2e055 100644
--- a/umbraco.MacroEngines.Juno/Properties/AssemblyInfo.cs
+++ b/umbraco.MacroEngines.Juno/Properties/AssemblyInfo.cs
@@ -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
diff --git a/umbraco.MacroEngines.Juno/RazorBuildProvider.cs b/umbraco.MacroEngines.Juno/RazorBuildProvider.cs
new file mode 100644
index 0000000000..e76cd68eb4
--- /dev/null
+++ b/umbraco.MacroEngines.Juno/RazorBuildProvider.cs
@@ -0,0 +1,11 @@
+namespace umbraco.MacroEngines {
+
+ ///
+ /// Stub Build Provider If Want To Implement Anything Advanced In The Future
+ /// Also Allows Us To Register Build Provider In Medium Trust
+ ///
+ public class RazorBuildProvider : System.Web.WebPages.Razor.RazorBuildProvider {
+
+ }
+
+}
diff --git a/umbraco.MacroEngines.Juno/RazorMacroEngine.cs b/umbraco.MacroEngines.Juno/RazorMacroEngine.cs
index da8b3da022..2398f9e958 100644
--- a/umbraco.MacroEngines.Juno/RazorMacroEngine.cs
+++ b/umbraco.MacroEngines.Juno/RazorMacroEngine.cs
@@ -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(@"
", macro.Alias));
- razorWebPage.ExecutePageHierarchy(new WebPageContext(httpContext, razorWebPage, null), output);
- if (isDebugMode) {
- sw.Stop();
- output.Write(string.Format("Taken {0}ms", sw.ElapsedMilliseconds));
- output.Write("
");
- }
+ 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("
Error loading Razor Script (file: {0})", 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("
Error loading Razor Script {0}", macro.ScriptName);
if (GlobalSettings.DebugMode)
loading = loading + exception.Message;
loading = loading + "
";
return loading;
}
}
+
#endregion
}
}
\ No newline at end of file