'Razor engine cant find view

I'm trying to render a HTML from a view without using a web request. I need the HTML as a string, internally, I do not wish to serve it.

The viewEngine.FindView() returns a viewEnineResult that shows no view was found. It shows to search locations where it looked they look like this:

/Views//PDFOperationsReportView.cshtml

/Views/Shared/PDFOperationsReportView.cshtml

(Observe the double forward slash in the first line)

File structure (I placed it into a HTML snippet cause I couldn't manage to format the text properly in this editor)

Project 
      Folder 
        Subfolder
            CodeFile.cs
      Views
        PDFOperationsReportView.cshtml

The code:

var viewName = "PDFOperationsReportView";
var actionContext = GetActionContext();
var viewEngineResult = _viewEngine.FindView(actionContext, viewName, false);
if (!viewEngineResult.Success)
{
    throw new InvalidOperationException(string.Format("Couldn't find view '{0}'", viewName));
}
            
var view = viewEngineResult.View;


Solution 1:[1]

I had the same issue. I found the answer here: GitHub aspnet/Mvc Issue #4936

Basically, use GetView instead of FindView, like this:

var viewResult = razorViewEngine.GetView(viewName, viewName, false);

Your viewName needs to be a full path for this to work. For example:

  1. /Views/Shared/PDFOperationsReportView.cshtml
  2. ~/Pages/Shared/_Article.cshtml
  3. ~/Areas/CM/Pages/_Article.cshtml

Solution 2:[2]

We have a helper method defined to render optional views which may or may not exist:

public static Task RenderPartialAsyncIfExists(this IHtmlHelper htmlHelper, ICompositeViewEngine engine, string partialViewName, object model)
{
    if (engine.GetView(partialViewName, partialViewName, false).Success)
    {
        return htmlHelper.RenderPartialAsync(partialViewName, model);
    }

    return Task.CompletedTask;
}

It's used on view pages like:

@inject ICompositeViewEngine Engine
...
@{ await Html.RenderPartialAsyncIfExists(Engine, $"~/Views/Shared/_navigationAdmin.cshtml"); }

This works find locally (IIS Express) but for some reason was failing when deployed to IIS.

In my case, there was something wrong with the .csproj file, where the view in question was removed but then re-added as an embedded resource:

    <ItemGroup>
        <Content Remove="Views\Shared\_navigationAdmin.cshtml" />
    </ItemGroup>
    
    <ItemGroup>
        <EmbeddedResource Include="Views\Shared\_navigationAdmin.cshtml" />
    </ItemGroup>

Removing those two sections from the .csproj fixed the problem in IIS.

This is using (EOL) AspNet Core 2.2

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 carlin.scott
Solution 2 BurnsBA