Skip to content

Instantly share code, notes, and snippets.

@mwikstrom
Created December 12, 2015 15:31
Show Gist options
  • Save mwikstrom/ea2b90fd0d306ba3498c to your computer and use it in GitHub Desktop.
Save mwikstrom/ea2b90fd0d306ba3498c to your computer and use it in GitHub Desktop.
using RazorEngine.Templating;
using System;
using System.Collections.Generic;
using System.Security;
using System.Web.Razor;
namespace YourNamespace
{
public class Global : System.Web.HttpApplication
{
// NOTICE: This code is just for testing. It will create a new app domain for every request which
// is a very bad idea!
protected void Application_BeginRequest(object sender, EventArgs e)
{
// COPY FROM https://github.com/knightmeister/RazorEngineIssue/blob/master/Global.asax.cs (line 25-38)
// init razor
var razor = IsolatedRazorEngineService.Create(() => createRazorSandbox());
// create the content model
ContentModel cm = new ContentModel();
cm.Html = "<h1>html here</h1>";
cm.Title = "Title";
var authors = new List<UserDetail>();
authors.Add(new UserDetail() { EmailAddress = "hello@world.com", Name = "Test" });
cm.History.Authors = authors;
// run the transform
// EDIT: Use another template to ensure we really can render user details from the authors list
//string template = "@Model.Html";
string template = "@Model.History.Authors[0].EmailAddress";
// EDIT: Ditch RazorDynamicObject
// string result = razor.RunCompile(template, "name", typeof(ContentModel), RazorDynamicObject.Create(cm));
string result = razor.RunCompile(template, "name", typeof(ContentModel), cm);
// END COPY
this.Response.Write(result);
this.Response.End();
}
// COPY FROM https://github.com/knightmeister/RazorEngineIssue/blob/master/Global.asax.cs (line 43-65)
private static AppDomain createRazorSandbox()
{
System.Security.Policy.Evidence ev = new System.Security.Policy.Evidence();
ev.AddHostEvidence(new System.Security.Policy.Zone(SecurityZone.Internet));
PermissionSet permSet = SecurityManager.GetStandardSandbox(ev);
// We have to load ourself with full trust
System.Security.Policy.StrongName razorEngineAssembly = typeof(RazorEngineService).Assembly.Evidence.GetHostEvidence<System.Security.Policy.StrongName>();
// We have to load Razor with full trust (so all methods are SecurityCritical)
// This is because we apply AllowPartiallyTrustedCallers to RazorEngine, because
// We need the untrusted (transparent) code to be able to inherit TemplateBase.
// Because in the normal environment/appdomain we run as full trust and the Razor assembly has no security attributes
// it will be completely SecurityCritical.
// This means we have to mark a lot of our members SecurityCritical (which is fine).
// However in the sandbox domain we have partial trust and because razor has no Security attributes that means the
// code will be transparent (this is where we get a lot of exceptions, because we now have different security attributes)
// To work around this we give Razor full trust in the sandbox as well.
System.Security.Policy.StrongName razorAssembly = typeof(RazorTemplateEngine).Assembly.Evidence.GetHostEvidence<System.Security.Policy.StrongName>();
AppDomainSetup adSetup = new AppDomainSetup();
// EDIT: Append \bin to application base path
adSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "\\bin";
AppDomain newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, razorEngineAssembly, razorAssembly);
return newDomain;
}
}
// COPY FROM: https://github.com/knightmeister/RazorEngineIssue/blob/master/Models/Models.cs
[Serializable] // EDIT: Mark as serializable
public class ContentModel
{
public string Html { get; set; }
public string Title { get; set; }
public EditHistory History { get; set; }
public ContentModel()
{
History = new EditHistory();
}
}
[Serializable] // EDIT: Mark as serializable
public class EditHistory
{
// EDIT: Changed from collection to list so that we can use indexer in template.
public IReadOnlyList<UserDetail> Authors { get; set; }
public EditHistory()
{
Authors = new List<UserDetail>();
}
}
[Serializable] // EDIT: Mark as serializable
public class UserDetail
{
public string Name { get; set; }
public string EmailAddress { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment