RazorLight
使用Razor从文件 /嵌入式 /字符串 /数据库或ASP.NET MVC之外的自定义源构建模板。没有冗余的依赖和解决方案,具有出色的性能和.NET标准2.0和.NET Core 3.0支持。
乌克兰的团结
亲爱的朋友,我叫伊万,我是创建这个图书馆的人。我住在乌克兰,如果您正在阅读此消息 – 我真的希望您和您的家人安全健康。 2月24日,俄罗斯从东到西部的整个乌克兰席卷了我的国家。他们开始摧毁军事基础设施,所谓的“特殊行动”实际上是对我们的全面战争。
更新:自从我第一次发布此消息以来已经很长时间了。感谢您的巨大支持,我正在删除我的志愿者捐赠帐户,而是为您提供了乌克兰最大且经过验证的慈善组织-Checbackalive。如果您有可能和渴望帮助乌克兰的愿望 – 那是您宝贵捐款的正确位置。谢谢。安全
目录
- Quickstart
- 模板源
- 文件
- 嵌入式资源
- 数据库(自定义)
- 包括(又称部分)
- 编码
- 其他元数据参考
- 启用Intellisense支持
- 常问问题
Quickstart
使用以下命令安装Nuget软件包:
Install-Package RazorLight -Version 2.3.0
最简单的情况是从字符串创建模板。每个模板必须具有与之关联的模板键,因此您可以下次呈现相同的模板而无需重新编译。
RazorLightEngineBuilder()
// required to have a default RazorLight Project type,
// but not required to create a template from string.
.UseEmbeddedResourcesProject(typeof(ViewModel))
.SetOperatingAssembly(typeof(ViewModel).Assembly)
.UseMemoryCachingProvider()
.Build();
string template = \”Hello, @Model.Name. Welcome to RazorLight repository\”;
ViewModel model = new ViewModel {Name = \”John Doe\”};
string result = await engine.CompileRenderStringAsync(\”templateKey\”, template, model);\”>
var engine = new RazorLight EngineBuilder ( ) // required to have a default RazorLight Project type, // but not required to create a template from string. . UseEmbeddedResourcesProject ( typeof ( ViewModel ) ) . SetOperatingAssembly ( typeof ( ViewModel ) . Assembly ) . UseMemoryCachingProvider ( ) . Build ( ) ; string template = \"Hello, @Model.Name. Welcome to RazorLight repository\" ; ViewModel model = new ViewModel { Name = \"John Doe\" } ; string result = await engine . CompileRenderStringAsync ( \"templateKey\" , template , model ) ;
摘要源|锚
渲染一个编译的模板:
var cacheResult = engine . Handler . Cache . RetrieveTemplate ( \"templateKey\" ) ; if ( cacheResult . Success ) { var templatePage = cacheResult . Template . TemplatePageFactory ( ) ; string result = await engine . RenderTemplateAsync ( templatePage , model ) ; }
摘要源|锚
模板源
RazorLight可以从任何来源解析模板,但是有一个内置的提供商可以从文件系统和嵌入式资源中解析模板源。
文件源
当从文件系统中解析模板时,TemplateKey-是通向RazorLight Engine Builder的根文件夹的相对路径。
RazorLightEngineBuilder()
.UseFileSystemProject(\”C:/RootFolder/With/YourTemplates\”)
.UseMemoryCachingProvider()
.Build();
var model = new {Name = \”John Doe\”};
string result = await engine.CompileRenderAsync(\”Subfolder/View.cshtml\”, model);\”>
var engine = new RazorLight EngineBuilder ( ) . UseFileSystemProject ( \"C:/RootFolder/With/YourTemplates\" ) . UseMemoryCachingProvider ( ) . Build ( ) ; var model = new { Name = \"John Doe\" } ; string result = await engine . CompileRenderAsync ( \"Subfolder/View.cshtml\" , model ) ;
摘要源|锚
EmbeddedResource来源
对于嵌入式资源,键是该模板与模板的文件名相结合的项目的命名空间。
以下示例使用了此项目结构:
Project/
Model.cs
Program.cs
Project.csproj
Project.Core/
EmailTemplates/
Body.cshtml
Project.Core.csproj
SomeService.cs
RazorLightEngineBuilder()
.UseEmbeddedResourcesProject(typeof(SomeService).Assembly)
.UseMemoryCachingProvider()
.Build();
var model = new Model();
string html = await engine.CompileRenderAsync(\”EmailTemplates.Body\”, model);\”>
var engine = new RazorLight EngineBuilder ( ) . UseEmbeddedResourcesProject ( typeof ( SomeService ) . Assembly ) . UseMemoryCachingProvider ( ) . Build ( ) ; var model = new Model ( ) ; string html = await engine . CompileRenderAsync ( \"EmailTemplates.Body\" , model ) ;
摘要源|锚
设置根名称空间可让您在提供模板名称作为键时将其删除:
RazorLightEngineBuilder()
.UseEmbeddedResourcesProject(typeof(SomeService).Assembly, \”Project.Core.EmailTemplates\”)
.UseMemoryCachingProvider()
.Build();
var model = new Model();
string html = await engine.CompileRenderAsync(\”Body\”, model);\”>
var engine = new RazorLight EngineBuilder ( ) . UseEmbeddedResourcesProject ( typeof ( SomeService ) . Assembly , \"Project.Core.EmailTemplates\" ) . UseMemoryCachingProvider ( ) . Build ( ) ; var model = new Model ( ) ; string html = await engine . CompileRenderAsync ( \"Body\" , model ) ;
摘要源|锚
自定义来源
如果将模板存储在数据库中 – 建议创建负责从中获得GetTings模板源的自定义RazorLight项目。该类将用于获取模板源和ViewImports。当您在模板内指定它时, RazorLight将使用它来解决布局。
RazorLightEngineBuilder()
.UseProject(project)
.UseMemoryCachingProvider()
.Build();
// For key as a GUID
string result = await engine.CompileRenderAsync(\”6cc277d5-253e-48e0-8a9a-8fe3cae17e5b\”, new { Name = \”John Doe\” });
// Or integer
int templateKey = 322;
string result = await engine.CompileRenderAsync(templateKey.ToString(), new { Name = \”John Doe\” });\”>
var project = new EntityFrameworkRazorProject ( new AppDbContext ( ) ) ; var engine = new RazorLight EngineBuilder ( ) . UseProject ( project ) . UseMemoryCachingProvider ( ) . Build ( ) ; // For key as a GUID string result = await engine . CompileRenderAsync ( \"6cc277d5-253e-48e0-8a9a-8fe3cae17e5b\" , new { Name = \"John Doe\" } ) ; // Or integer int templateKey = 322 ; string result = await engine . CompileRenderAsync ( templateKey . ToString ( ) , new { Name = \"John Doe\" } ) ;
您可以在这里找到一个完整的示例
包括(又名部分视图)
当您要在不同视图之间共享模板的可重复使用部分时,包括功能很有用。包括将大型模板分解为较小组件的有效方法。它们可以减少模板内容的重复,并允许重复使用元素。此功能要求您使用RazorLight项目系统,否则无法找到部分。
@model MyProject . TestViewModel < div > Hello @Model . Title < / div > @ { await IncludeAsync ( \" SomeView . cshtml \" , Model ) ; }
第一个参数采用模板的键来解决,第二个参数是视图的模型(可以为null)
编码
通过默认的RazorLight将模型值编码为HTML,但有时您想按原样输出它们。您可以使用@raw()函数禁用特定值编码
/* With encoding (default) */ string template = \"Render @Model.Tag\" ; string result = await engine . CompileRenderAsync ( \"templateKey\" , template , new { Tag = \"<html>&\" } ) ; Console . WriteLine ( result ) ; // Output: <html>& /* Without encoding */ string template = \"Render @Raw(Model.Tag)\" ; string result = await engine . CompileRenderAsync ( \"templateKey\" , template , new { Tag = \"<html>&\" } ) ; Console . WriteLine ( result ) ; // Output: <html>&
为了禁用整个文档的编码 – 只需将“禁用编码”变量设置为true
@model TestViewModel
@{
DisableEncoding = true;
}
< html >
Hello @Model.Tag
</ html >
启用Intellisense支持
Visual Studio Tooling对RazorLight并不了解您正在使用的视图 – 是典型的ASP.NET MVC模板。为了启用RazorLight模板的Intellisense,您应该给Visual Studio关于基本模板类的一些暗示,所有模板都隐含地继承
RazorLight
@inherits TemplatePage<MyModel>
<html>
Your awesome template goes here, @Model.Name
</html>\”>
@using RazorLight @inherits TemplatePage < MyModel > < html > Your awesome template goes here , @Model . Name < / html >
常问问题
编码挑战(FAQ)
如何在不设置项目的情况下使用内存模板?
简短的答案是,您必须设置一个项目以使用内存缓存提供商。该项目不必做任何事情。这是通过设计,因为没有项目系统, RazorLight无法找到部分视图。
您曾经能够写作:
RazorLightEngineBuilder()
.UseMemoryCachingProvider()
.Build();\”>
var razorEngine = new RazorLight EngineBuilder ( ) . UseMemoryCachingProvider ( ) . Build ( ) ;
…但是现在这引发了一个例外,说:“ _ RazorLight项目不能无效”。
✔️
RazorLightEngineBuilder()
.UseEmbeddedResourcesProject(typeof(AnyTypeInYourSolution)) // exception without this (or another project type)
.UseMemoryCachingProvider()
.Build();\”>
var razorEngine = new RazorLight EngineBuilder ( ) . UseEmbeddedResourcesProject ( typeof ( AnyTypeInYourSolution ) ) // exception without this (or another project type) . UseMemoryCachingProvider ( ) . Build ( ) ;
情感: RazorLight -2.0.0 -Beta1及以后。
原始问题:#250
如何在电子邮件中嵌入图像?
这不是RazorLight问题,但请参阅此stackoverflow答案。
如何将CSS嵌入电子邮件中?
这不是RazorLight问题,但请查看Premailer.net。
汇编和部署问题(FAQ)
RazorLight的大多数问题都涉及将其部署在新计算机,在Docker容器中等。
其他元数据参考
当RazorLight编译您的模板时 – 它加载了从您的条目组件中加载所有组件并从中创建元数据。这是一种默认策略,在99%的时间内起作用。但是有时汇编崩溃了,有一个例外消息,例如“找不到汇编my.super.sembly2000”。为了解决此问题,您可以将其他元数据引用到RazorLight 。
RazorLightEngineBuilder()
.UseMemoryCachingProvider()
.AddMetadataReferences(metadataReference)
.Build();\”>
var metadataReference = MetadataReference . CreateFromFile ( \"path-to-your-assembly\" ) var engine = new RazorLight EngineBuilder ( ) . UseMemoryCachingProvider ( ) . AddMetadataReferences ( metadataReference ) . Build ( ) ;
使用运行时编译时,我在升级到ASP.NET Core 3.0后会遇到错误
请参阅:https://docs.microsoft.com/en-us/aspnet/core/razor-pages/sdk?view= aspnetcore-3.1#use-the-razor-sdk
从ASP.NET Core 3.0开始,如果禁用了项目文件中的RazorCompileOnBuild或RazorCompileOnPublish属性,则默认情况下,MVC视图或剃刀页面不会提供。应用程序必须向Microsoft.aspnetcore.mvc.razor.runtimecompilation添加明确的引用,如果该应用程序依赖于运行时编译来处理.cshtml文件。
升级到RazorLight -2.0.0 -Beta2或更高版本后,我会得到一个null参考异常。
最常见的情况是,有些人使用RazorLight的能力将原始字符串作为模板。尽管这仍然受到支持(您无法使用诸如部分视图之类的高级功能),但不支持的内容(现在)是使用带有原始字符串的缓存提供商。解决方法是使用虚拟课程。
当我在另一台服务器上部署此库时,我会得到“找不到编译库”
将这些属性组添加到您的入口点CSPROJ中。它必须是入口点项目。例如:ASP.NET核心Web项目,.NET Core Console Project等。
RazorLight on .NET Core –>
<PreserveCompilationContext>true</PreserveCompilationContext>
<MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
</PropertyGroup>\”>
< PropertyGroup > <!-- This group contains project properties for RazorLight on .NET Core --> < PreserveCompilationContext >true</ PreserveCompilationContext > < MvcRazorCompileOnPublish >false</ MvcRazorCompileOnPublish > < MvcRazorExcludeRefAssembliesFromPublish >false</ MvcRazorExcludeRefAssembliesFromPublish > </ PropertyGroup >
我得到的“无法从入口组件中加载元数据参考”例外
将PreserVecompilationContext设置为您的 *.csproj文件的属性组标签中的true。
< PropertyGroup > ... < PreserveCompilationContext >true</ PreserveCompilationContext > </ PropertyGroup >
此外, RazorLight允许您专门找到您找不到的任何元数据,如果您以SCD(独立的部署)模式运行,可能会发生这种情况,因为RazorLight使用的C#编译器需要能够找到mscorlib.dll。如果将来的.NET SDK工具的未来版本具有不良的MSBUILD目标,那么这可能是一个有用的技巧,而MSBUILD目标不莫名其妙地“保留编译上下文”,并且在等待Microsoft支持时需要立即修复。
我得到的“找不到参考组件\’Microsoft.aspnetcore.antiforgery.dll\’”。
默认情况下,3.0 SDK避免将引用复制到构建输出。将PreserVecompilationReferences和PreserVecompilationContext设置为您的 *.csproj文件的属性集群标签中的true。
< PropertyGroup > < PreserveCompilationReferences >true</ PreserveCompilationReferences > < PreserveCompilationContext >true</ PreserveCompilationContext > </ PropertyGroup >
有关更多信息,请参见dotnet/aspnetcore#14418(注释)(讨论上述标志)和Microsoft/DockerTools#217(注释)(讨论了在ASP.NET Core 2.2中标记了运行时编译功能,并从ASP.NET CORE CORE CORE CORE CORE 3.0中删除了ASP.NET Core 2.2中的过时。
RazorLight在AWS Lambda或Azure功能上无法正常工作
尚未支持无服务器解决方案。但是,对于Azure功能,一些用户报告了Azure功能的成功3.0.3。截至6/3/2020,Azure函数SDK团队已经确认了Azure功能的Removeruntimencies intipencies任务中的一个错误,影响了Azure函数3.0.4-3.0.6版本。
对于Azure函数3.0.4-3.0.5,已知的解决方法是禁用“ Azure函数依赖性修剪”。要禁用依赖性修剪,请在您的root / entrypoint项目中添加以下内容:
< PropertyGroup > < _FunctionsSkipCleanOutput >true</ _FunctionsSkipCleanOutput > </ PropertyGroup >
此外,Azure函数还具有未偿式拉动请求,以更新runtimeassemblies。
不受支持的场景
RazorLight不适用于ASP.NET核心集成测试
RazorLight目前尚未旨在支持此类集成测试。如果您需要测试RazorLight测试,那么当前的建议就是简单地创建一个名为<YourCompanyName>的项目。<YourProjectName> .templating并将模板渲染层作为域服务,然后对该服务编写测试。然后,您可以在集成测试中模拟RazorLight的任何依赖项。
如果您碰巧可以使用此功能,请让我们知道您的所作所为。
