c# razorengine

c# - Diseños de RazorEngine



(3)

Estoy usando el motor de Razor https://github.com/Antaris/RazorEngine para analizar el cuerpo de mis plantillas de correo electrónico. ¿Es posible definir un diseño e incluir otros archivos .cshtml? por ejemplo, un encabezado común y un pie de página.


Conseguí plantillas comunes y un diseño funcional, con la ayuda de estas dos publicaciones:

RazorEngine cadenas de diseños y secciones?

http://blogs.msdn.com/b/hongyes/archive/2012/03/12/using-razor-template-engine-in-web-api-self-host-application.aspx

Esta es mi solución:

Solución 1: Diseño

Se utiliza para establecer _Layout

@{ _Layout = "Layout.cshtml"; ViewBag.Title = Model.Title; }

Pie de página

@section Footer { @RenderPart("Footer.cshtml") }

Layout.cshtml

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> </head> <body> <div id="content"> @RenderBody() </div> @if (IsSectionDefined("Footer")) { <div id="footer"> @RenderSection("Footer") </div> } </body> </html>

TemplateBaseExtensions

Extienda TemplateBase con un método RenderPart

public abstract class TemplateBaseExtensions<T> : TemplateBase<T> { public string RenderPart(string templateName, object model = null) { string path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Templates", templateName); return Razor.Parse(File.ReadAllText(path), model); } }

Maquinilla de afeitar

Establezca BaseTemplateType en su clase TemplateBaseExtensions

TemplateServiceConfiguration templateConfig = new TemplateServiceConfiguration { BaseTemplateType = typeof(TemplateBaseExtensions<>) }; Razor.SetTemplateService(new TemplateService(templateConfig));

Editar Solución 2:

Si está utilizando un TemplateResolver. RenderPart no es necesario usar el @Include en su lugar

Pie de página

@section Footer { @Include("Footer.cshtml") }

Resolución

public class TemplateResolver : ITemplateResolver { public string Resolve(string name) { if (name == null) { throw new ArgumentNullException("name"); } string path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Templates", name); return File.ReadAllText(path, System.Text.Encoding.Default); } }

Config

TemplateServiceConfiguration templateConfig = new TemplateServiceConfiguration { Resolver = new TemplateResolver() }; Razor.SetTemplateService(new TemplateService(templateConfig));

Actualización de The Muffin Man Especifique una plantilla y renderice una cadena

var templateResolver = Razor.Resolve("Registration.cshtml"); return templateResolver.Run(new ExecuteContext());

También yo, junto con otros en este enlace https://github.com/Antaris/RazorEngine/issues/61 tuve problemas con el uso de _Layout mientras que Layout funcionó.

''_Layout'' es la sintaxis antigua. Se actualizó a ''Diseño'' en una versión futura.


La forma más fácil de implementar un diseño con RazorEngine es reemplazando lo que devuelve su plantilla en @RenderBody () del diseño:

var finalHtml = layout.Replace(@"@RenderBody()", templateHtml);

P.ej:

Tu _Layout.cshtml con el típico @RenderBody ()

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> </head> <body> <div> @RenderBody() </div> </body> </html>

Tu plantilla RazorEngine MyTemplate.cshtml

@using RazorEngine.Templating @inherits TemplateBase<myviewmodel> <h1>Hello People</h1> <p>@Model</p>

Y donde sea que llames la plantilla RazorEngine:

var TemplateFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EmailTemplates"); var template = File.ReadAllText(Path.Combine(TemplateFolderPath,"MyTemplate.cshtml")); var layout = File.ReadAllText(Path.Combine(TemplateFolderPath, "_Layout.cshtml")); var templateService = new TemplateService(); var templateHtml = templateService.Parse(template, myModel, null, null); var finalHtml = layout.Replace(@"@RenderBody()", templateHtml);


Puedes hacer muchas cosas fácilmente con Razor; Sin embargo, ese proyecto en particular parece abstraer un montón de cosas del motor de Razor que podrías hacer (lo que es bueno y malo). En su situación, parece que estaría mucho mejor implementando su propia solución Razor (en realidad no es tan malo) y luego puede hacer que sus plantillas lancen excepciones o atraigan otro contenido con bastante facilidad.

Por ejemplo; Rodar su propia solución le permite crear una clase base para sus plantillas de maquinilla de afeitar que puede exponer la capacidad de obtener "vistas parciales" invocando otras plantillas. Además, puede realizar verificaciones de modelos y lanzar excepciones si ciertas propiedades son nulas.