/// <summary>Prepares the template.</summary> /// <param name="assemblyPath">The assembly path.</param> /// <param name="typeName">Name of the type.</param> /// <param name="viewBag">The view bag.</param> /// <param name="templateCache">The template cache.</param> /// <param name="encoding">The encoding.</param> private TemplateBase PrepareTemplate(string assemblyPath, string typeName, DynamicViewBag viewBag, TemplateCache templateCache, TemplateEncoding encoding = TemplateEncoding.Html) { var type = GetTemplateType(assemblyPath, typeName); var templateInstance = Activator.CreateInstance(type); if (templateInstance is TemplateBase) { var template = (TemplateBase)templateInstance; template.Encoding = encoding; template.ViewBag = viewBag; template.TemplateResolver = tpl => { string tplAssemblyPath = templateCache.Get(tpl, template: null, timestamp: null); if (String.IsNullOrWhiteSpace(tplAssemblyPath)) { return(null); } var layoutType = GetTemplateType(tplAssemblyPath, templateNamespace + "." + tpl); return(Activator.CreateInstance(layoutType) as ITemplate); }; return(template); } throw new ArgumentException("Invalid template type!"); }
/// <summary>Initializes a new instance of the <see cref="RazorTemplater" /> class.</summary> /// <param name="templateAssemblyPath">The template assembly path. This is the path where the generated templates are stored/cached. /// If shadow copy is enabled this path will be ignored and the shadow copy path will be used.</param> /// <param name="renderTimeout">The render timeout. This is the time in ms a template is allowed to render itself.</param> /// <param name="templateNamespace">The template namespace.</param> /// <param name="allowedDirectories">The directories the templates are allowed to read from.</param> /// <param name="baseType">Type of the template base class. Defaults to <see cref="TemplateBase" />.</param> /// <param name="defaultNamespaces">The default namespaces. Defaults to "System", "System.Collections.Generic", "System.Linq" and "System.Text".</param> /// <param name="forbiddenTypes">The forbidden types (FQDN). Defaults to "Task", "Thread", "System.Activator" and "System.Reflection.Assembly".</param> /// <param name="language">The language. Defaults to C#.</param> /// <param name="sponsor">The sponsor to keep the object alive.</param> /// <param name="persistTemplates">If set to <c>true</c> the generated templates are persisted over multiple application runs. Otherwise they are deleted when disposing.</param> public RazorTemplater(string templateAssemblyPath, int renderTimeout = 5000, string templateNamespace = "IsolatedRazor.RazorTemplate", List <string> allowedDirectories = null, Type baseType = null, List <string> defaultNamespaces = null, List <string> forbiddenTypes = null, RazorCodeLanguage language = null, ClientSponsor sponsor = null, bool persistTemplates = false) { RenderTimeout = renderTimeout; this.templateNamespace = templateNamespace; this.persistTemplates = persistTemplates; DefaultNamespaces = defaultNamespaces ?? new List <string>() { "System", "System.Collections.Generic", "System.Net", "System.Linq", "System.Text", "IsolatedRazor" }; ForbiddenTypes = forbiddenTypes ?? new List <string>() { "System.Threading.Tasks.Task", "System.Threading.Tasks.Task`1", "System.Threading.Thread", "System.Activator", "System.Reflection.Assembly" }; clientSponsor = sponsor ?? new ClientSponsor(TimeSpan.FromMinutes(1)); defaultBaseClass = (baseType ?? typeof(TemplateBase)).FullName; var host = new RazorEngineHost(language ?? new CSharpRazorCodeLanguage()) { DefaultNamespace = templateNamespace }; DefaultNamespaces.ForEach(n => host.NamespaceImports.Add(n)); engine = new RazorTemplateEngine(host); provider = host.CodeLanguage.LanguageName == "vb" ? (CodeDomProvider) new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider() : new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider(); adSetup = new AppDomainSetup(); if (AppDomain.CurrentDomain.SetupInformation.ShadowCopyFiles == "true") { isShadowCopied = true; templatePath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.CachePath, AppDomain.CurrentDomain.SetupInformation.ApplicationName); var shadowCopyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (shadowCopyDir.Contains("assembly")) { shadowCopyDir = shadowCopyDir.Substring(0, shadowCopyDir.LastIndexOf("assembly")); } var privatePaths = new List <string>(); foreach (var assemblyLocation in AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic && a.Location.StartsWith(shadowCopyDir)).Select(a => a.Location)) { privatePaths.Add(Path.GetDirectoryName(assemblyLocation)); } adSetup.ApplicationBase = shadowCopyDir; adSetup.PrivateBinPath = String.Join(";", privatePaths); } else { isShadowCopied = false; templatePath = templateAssemblyPath; adSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; adSetup.PrivateBinPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath; } var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(Path.GetDirectoryName(adSetup.ApplicationBase)); readerParameters = new ReaderParameters() { AssemblyResolver = resolver }; if (templateCache == null) { var path = Path.Combine(templatePath, TEMPLATE_CACHE_FILE); if (persistTemplates && File.Exists(path)) { using (var filestream = File.Open(path, FileMode.Open)) { var formatter = new BinaryFormatter(); templateCache = (TemplateCache)formatter.Deserialize(filestream); } } else { templateCache = new TemplateCache(); } } Directory.CreateDirectory(templatePath); permissionSet = new PermissionSet(PermissionState.None); permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); // run the code permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.RemotingConfiguration)); // remoting lifetime (sponsor) permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, templatePath)); // read templates permissionSet.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)); // support dynamic if (allowedDirectories != null) { allowedDirectories.ForEach(dir => permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, dir))); } RecycleAppDomain(); }
/// <summary>Renders the template with the given model.</summary> /// <typeparam name="T">Type of the model.</typeparam> /// <param name="assemblyPath">The assembly path.</param> /// <param name="typeName">Name of the type.</param> /// <param name="model">The model.</param> /// <param name="viewBag">The view bag.</param> /// <param name="templateCache">The template cache.</param> /// <param name="encoding">The encoding.</param> internal string RenderTemplateInternal <T>(string assemblyPath, string typeName, T model, DynamicViewBag viewBag, TemplateCache templateCache, TemplateEncoding encoding = TemplateEncoding.Html) { var template = PrepareTemplate(assemblyPath, typeName, viewBag, templateCache, encoding) as ITemplate <T>; template.Model = model; return(template.Render()); }