Search code examples
c#razorasp.net-coreasp.net-core-mvc

Render Razor View to string in ASP.NET Core


I use RazorEngine for parsing of templates in my MVC 6 project like this:

Engine.Razor.RunCompile(File.ReadAllText(fullTemplateFilePath), templateName, null, model);

It works fine for the beta 6. It does not work after upgrading to beta 7 with the error:

MissingMethodException: Method not found: "Void Microsoft.AspNet.Razor.CodeGenerators.GeneratedClassContext.set_ResolveUrlMethodName(System.String)". in RazorEngine.Compilation.CompilerServiceBase.CreateHost(Type templateType, Type modelType, String className)

This is global.json:

{
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-beta7",
    "runtime": "clr",
    "architecture": "x64"
  }
}

This is project.json:

...
"dependencies": {
    "EntityFramework.SqlServer": "7.0.0-beta7",
    "EntityFramework.Commands": "7.0.0-beta7",
    "Microsoft.AspNet.Mvc": "6.0.0-beta7",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta7",
    "Microsoft.AspNet.Authentication.Cookies": "1.0.0-beta7",
    "Microsoft.AspNet.Authentication.Facebook": "1.0.0-beta7",
    "Microsoft.AspNet.Authentication.Google": "1.0.0-beta7",
    "Microsoft.AspNet.Authentication.MicrosoftAccount": "1.0.0-beta7",
    "Microsoft.AspNet.Authentication.Twitter": "1.0.0-beta7",
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta7",
    "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-beta7",
    "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-beta7",
    "Microsoft.AspNet.Server.IIS": "1.0.0-beta7",
    "Microsoft.AspNet.Server.WebListener": "1.0.0-beta7",
    "Microsoft.AspNet.StaticFiles": "1.0.0-beta7",
    "Microsoft.AspNet.Tooling.Razor": "1.0.0-beta7",
    "Microsoft.Framework.Configuration.Abstractions": "1.0.0-beta7",
    "Microsoft.Framework.Configuration.Json": "1.0.0-beta7",
    "Microsoft.Framework.Configuration.UserSecrets": "1.0.0-beta7",
    "Microsoft.Framework.Logging": "1.0.0-beta7",
    "Microsoft.Framework.Logging.Console": "1.0.0-beta7",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta7",
    "RazorEngine": "4.2.2-beta1"
  },
...
  "frameworks": {
    "dnx451": { }
  },
...

My template is:

@model dynamic
@{
    Layout = null;
}

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Registration</title>
</head>
<body>
<p>
    Hello, @Model
</p>
</body>
</html>

Does anyone have similar problems? There is another way to parse templates in MVC 6?


Solution

  • UPDATE July, 2016

    Working fine on the following versions 1.0.0, RC2


    Who's targeting aspnetcore RC2, this snippet might help you:

    • Create a separate Service, so you can use it either if you are not in a controller context, e.g. from a command line or on a queue runner, etc ...
    • Register this service in your IoC container in the Startup class

    https://gist.github.com/ahmad-moussawi/1643d703c11699a6a4046e57247b4d09

    Usage

    // using a Model
    string html = view.Render("Emails/Test", new Product("Apple"));
    
    // using a Dictionary<string, object>
    var viewData = new Dictionary<string, object>();
    viewData["Name"] = "123456";
    
    string html = view.Render("Emails/Test", viewData);
    

    Notes

    Links in Razor are rendered as relative URL, so this will not work on external views (like emails, etc ...).

    As for now am generating the link on the controller and pass it to the view through the ViewModel.

    Credit

    The source is extracted from (Thanks To @pholly): https://github.com/aspnet/Entropy/blob/dev/samples/Mvc.RenderViewToString/RazorViewToStringRenderer.cs)