有没有人设法用aspnet核心2.0运行RAZOR?我想用它代替非常依赖于Visual Studio的T4模板。
我已经设法获得了C#中间代码,但我仍然无法再将其转换为字符串。
1)我是否走在正确的道路上?
2)如何执行生成的C#代码(并且是字符串形式)?如果可能的话,我希望它与ASPNET CORE一样。
C#(生成器代码适用于stackoverflow)
https://dotnetfiddle.net/T6Slzp
视图\ MyView.cshtml
@{
string[] members = {"Jani", "Hege", "Kai", "Jim"};
int i = Array.IndexOf(members, "Kai")+1;
int len = members.Length;
string x = members[2-1];
}
<html>
<body>
<h3>The time is @DateTime.UtcNow</h3>
@foreach (var person in members)
{
<p>@person</p>
}
<p>The number of names in Members are @len</p>
<p>The person at position 2 is @x</p>
<p>Kai is now in position @i</p>
@{
var j = 0;
while (j < 5)
{
j += 1;
<p>Line @j</p>
}
}
</body>
</html>
输出字符串(C#代码)
// <auto-generated/>
#pragma warning disable 1591
namespace RuntimeNamespace
{
#line hidden
using System;
using System.Threading.Tasks;
internal class TestView : BaseView
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
#line 1 "TestView.cshtml"
string[] members = {"Jani", "Hege", "Kai", "Jim"};
int i = Array.IndexOf(members, "Kai")+1;
int len = members.Length;
string x = members[2-1];
#line default
#line hidden
WriteLiteral("\n<html>\n<body>\n <h3>The time is ");
#line 10 "TestView.cshtml"
Write(DateTime.UtcNow);
#line default
#line hidden
WriteLiteral("</h3>\n");
#line 11 "TestView.cshtml"
foreach (var person in members)
{
#line default
#line hidden
WriteLiteral(" <p>");
#line 13 "TestView.cshtml"
Write(person);
#line default
#line hidden
WriteLiteral("</p>\n");
#line 14 "TestView.cshtml"
}
#line default
#line hidden
WriteLiteral("\n <p>The number of names in Members are ");
#line 16 "TestView.cshtml"
Write(len);
#line default
#line hidden
WriteLiteral("</p>\n <p>The person at position 2 is ");
#line 17 "TestView.cshtml"
Write(x);
#line default
#line hidden
WriteLiteral("</p>\n <p>Kai is now in position ");
#line 18 "TestView.cshtml"
Write(i);
#line default
#line hidden
WriteLiteral("</p>\n\n");
#line 20 "TestView.cshtml"
var j = 0;
while (j < 5)
{
j += 1;
#line default
#line hidden
WriteLiteral(" <p>Line ");
#line 25 "TestView.cshtml"
Write(j);
#line default
#line hidden
WriteLiteral("</p>\n");
#line 26 "TestView.cshtml"
}
#line default
#line hidden
WriteLiteral("</body>\n</html>\n\n\n\n");
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591
答案 0 :(得分:2)
非常接近我会说。您可能还想查看Asp Net Core Scaffolding project on GitHub,因为它使用Razor的方式非常类似(这是Visual Studio for ASP .net Core项目中原生使用的脚手架工具)。
我的BaseView
与您的略有不同,但看起来您应该只需执行以下操作:
Type compiledType = Compile(cSharpDocument.GeneratedCode);
BaseView razorTemplate = (BaseView)Activator.CreateInstance(compiledType);
var result = await razorTemplate.ExecuteAsync();
string output = razorTemplate.ToString();
Compile
和GetAssembly
的实施方式如下:
private Type Compile(string content)
{
SyntaxTree[] syntaxTrees = new[] { CSharpSyntaxTree.ParseText(content) };
string dummyAssemblyName = Path.GetRandomFileName();
CSharpCompilation compilation = CSharpCompilation.Create(dummyAssemblyName,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
syntaxTrees: syntaxTrees,
references: _references);
Assembly result = GetAssembly(compilation);
Type type = result.GetExportedTypes().First();
return type;
}
private static Assembly GetAssembly(Compilation compilation)
{
using (MemoryStream ms = new MemoryStream())
{
EmitResult result = compilation.Emit(ms);
if (!result.Success)
{
DiagnosticFormatter formatter = new DiagnosticFormatter();
IEnumerable<string> errorMessages = result.Diagnostics
.Where(d => d.IsWarningAsError || d.Severity == DiagnosticSeverity.Error)
.Select(d => formatter.Format(d));
throw new Exception($"Errors encountered whilst compiling assembly: {String.Join(Environment.NewLine, errorMessages)}");
}
ms.Seek(0, SeekOrigin.Begin);
Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
return assembly;
}
}