herbergt
herbergt

Reputation: 159

Render razor page with RazorViewToStringRenderer and ServiceStack

I'm trying to render a razor page to send it as an email template. I'm adding the views on a Razor library and trying to render these from a ServiceStack project using this class. I'm getting the following error:

Application startup exception: System.AggregateException: One or more errors occurred. (Unable to find view '/Test.cshtml'. The following locations were searched:
/Test.cshtml)
---> System.InvalidOperationException: Unable to find view '/Test.cshtml'. The following locations were searched:
/Test.cshtml
 at web.RazorTemplates.RazorViewToStringRenderer.FindView(ActionContext actionContext, String viewName) in /Users/herber/Documents/repos/tests/web/web.RazorTemplates/RazorViewToStringRenderer.cs:line 86
 at web.RazorTemplates.RazorViewToStringRenderer.RenderViewToStringAsync[TModel](String viewName, TModel model) in /Users/herber/Documents/repos/tests/web/web.RazorTemplates/RazorViewToStringRenderer.cs:line 39
 --- End of inner exception stack trace ---
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at web.AppHost.Configure(Container container) in /Users/herber/Documents/repos/tests/ss-razor-library/web/web/Startup.cs:line 65
at ServiceStack.ServiceStackHost.Init() in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\ServiceStackHost.cs:line 282
at ServiceStack.NetCoreAppHostExtensions.UseServiceStack(IApplicationBuilder app, AppHostBase appHost) in C:\BuildAgent\work\3481147c480f4a2f\src\ServiceStack\AppHostBase.NetCore.cs:line 333
at web.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in /Users/herber/Documents/repos/tests/ss-razor-library/web/web/Startup.cs:line 44
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
at Microsoft.AspNetCore.Hosting.WebHost.BuildApplication()
    crit: Microsoft.AspNetCore.Hosting.WebHost[6]
    Application startup exception
    System.AggregateException: One or more errors occurred. (Unable to find view '/Test.cshtml'. The following locations were searched:
    /Test.cshtml)
    ---> System.InvalidOperationException: Unable to find view '/Test.cshtml'. The following locations were searched:
    /Test.cshtml

The repo can be found here. Just for testing purpose I'm trying to render the template form the app Startup class.

I can render the template from a regular .net core app but not from a ServiceStack app. The repo for a working example on a regular .net core app can be found here. The render is performed on index page

Upvotes: 1

Views: 672

Answers (1)

mythz
mythz

Reputation: 143319

These examples are not the same, you're rendering it from an MVC Controller:

public class IndexModel : PageModel
{
    private readonly ILogger<IndexModel> _logger;
    private readonly IRazorViewToStringRenderer _razorRenderer;

    public IndexModel(ILogger<IndexModel> logger, IRazorViewToStringRenderer razorRenderer)
    {
        _logger = logger;
        _razorRenderer = razorRenderer;
    }

    public void OnGet()
    {
        var body =  _razorRenderer.RenderViewToStringAsync("/Test.cshtml",new TestModel{Message = "World"}).Result;
        Console.WriteLine(body);
    }
}

vs On Startup before the App has been initialized:

public override void Configure(Container container)
{
    SetConfig(new HostConfig
    {
        DefaultRedirectPath = "/metadata",
        DebugMode = AppSettings.Get(nameof(HostConfig.DebugMode), false)
    });

    var razorRenderer = container.Resolve<IRazorViewToStringRenderer>();
    var body =  razorRenderer.RenderViewToStringAsync("/Test.cshtml",new TestModel()).Result;
    Console.WriteLine(body);
}

Since you're trying to use MVC's Razor implementation instead of ServiceStack.Razor you should be rendering it inside an MVC Controller or Razor page, not a ServiceStack AppHost or Service which has its own Razor implementation for usage in ServiceStack Services that uses its own stand-alone Razor APIs. If you're interested in using ServiceStack.Razor refer to the razor project template for a valid configuration.

Although since it's simpler, cleaner & more flexible than Razor & actually designed to be used in a stand-alone Sandbox, you should also consider ServiceStack #Script for rendering stand-alone templates, here's a rendering Email template example.

Upvotes: 1

Related Questions