Home Using “razor” outside of ASPNET Core 2.0
Reply: 1

Using “razor” outside of ASPNET Core 2.0

Junior
1#
Junior Published in 2018-01-10 02:08:38Z

Has anyone ever managed to run RAZOR out of aspnet core 2.0? I would like to use it in place of T4 templates that are very dependent on Visual Studio.

I already managed to get the C # intermediate code, but I still could not convert it to string again.

1) Am I on the right path?

2) How do I execute the C # code that was generated (and is in string form)? If possible, I would like it to be the same way as ASPNET CORE does.

C# (Generator code is extensive for stackoverflow)

https://dotnetfiddle.net/T6Slzp

Views\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>

Output string (C# code)

// <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
CalC
2#
CalC Reply to 2018-01-10 12:31:35Z

Pretty close I'd say. You might also want to check out the Asp Net Core Scaffolding project on GitHub as that uses Razor in a very similar way under the hood (this is the scaffolding tool used natively within Visual Studio for ASP .net Core projects).

My BaseView is slightly different to yours but it looks like you should just need to do the following:

Type compiledType = Compile(cSharpDocument.GeneratedCode);
BaseView razorTemplate = (BaseView)Activator.CreateInstance(compiledType);
var result = await razorTemplate.ExecuteAsync();
string output = razorTemplate.ToString();

Where Compile and GetAssembly are implemented as follows:

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;
    }
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.32447 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO