1

Issue

I currently have a .NET Core library that I am using to render Razor pages as HTML emails. I am following this tutorial. There are no errors during compile-time but at runtime I am getting the following error:

'Unable to find view '/Views/Emails/NewOrder/NewOrder.cshtml'. The following locations were searched: /Views/Emails/NewOrder/NewOrder.cshtml'

I have set the build action of NewOrder.cshtml to Content and I have set the copy to output directory to Copy Always. I am unsure to why this is unable to find the view as I can see in the bin\Debug\netcoreapp2.2\Views folder that the emails are being copied to the output directory.


Code

I am searching for the view with the following code:

private IView FindView(ActionContext actionContext, string viewName)
{
    var getViewResult = _viewEngine.GetView(executingFilePath: null, viewPath: viewName, isMainPage: true);
    if (getViewResult.Success)
    {
        return getViewResult.View;
    }

    var findViewResult = _viewEngine.FindView(actionContext, viewName, isMainPage: true);
    if (findViewResult.Success)
    {
        return findViewResult.View;
    }

    var searchedLocations = getViewResult.SearchedLocations.Concat(findViewResult.SearchedLocations);
    var errorMessage = string.Join(
        Environment.NewLine,
        new[] {$"Unable to find view '{viewName}'. The following locations were searched:"}.Concat(
            searchedLocations));

    throw new InvalidOperationException(errorMessage);
}
mvermef
  • 3,814
  • 1
  • 23
  • 36
Tachyon
  • 2,171
  • 3
  • 22
  • 46
  • This sounds like a routing issue, .net core has some default routes that it will look for to find a view which can be configured in your `startup.cs`. I have not used a `viewEngine` before but I would assume that you might need to configure or override its routes. Here is a link to a page giving more details about routing in .net core https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-2.2. If I were you I would probably move your views out of the bin and into a more controlled location. – A. Hasemeyer Mar 08 '19 at 20:33
  • Too many moving parts not enough details as to your setup. – mvermef Mar 09 '19 at 06:47

2 Answers2

2

It seemed that it was looking in the source directory instead of the actually executing assembly folder. I fixed it by changing the first line of the FindView method to the following:

var dir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var getViewResult = _viewEngine.GetView(executingFilePath: dir, viewPath: viewName, isMainPage: true);
Tachyon
  • 2,171
  • 3
  • 22
  • 46
0

Tachyon's answer worked for me. Here is the code I have:

var dir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
dir = Path.Combine(dir, "Templates");

var viewResult = _razorViewEngine.GetView(dir, "Index.cshtml", true);

Please note that I had to set the "Index.cshtml" file to be "copy if newer"

sean717
  • 11,759
  • 20
  • 66
  • 90