Issue of RazorViewEngine caching and Layout location in .NET Core

 

 

I recently tried to implement the razor  email template explained by Scott Sauber

Tutorial here: https://scottsauber.com/2018/07/07/walkthrough-creating-an-html-email-template-with-razor-and-razor-class-libraries-and-rendering-it-from-a-net-standard-class-library/

                         

All fine and dandy until I had issues regarding the template file. Problem was that even though the file is in ‘~\bin\Debug\netcoreapp2.2’ it searches for the template in the root folder such as ‘rootfolder\Views\Shared\_Layout.cshtml’ and not in ‘rootfolder\bin\Debug\netcoreapp2.2\Views\Shared\_Layout.cshtml’.

 

This is most likely generated by the fact that I have the views as an embedded resource in a CLASS LIBRARY and not in a Web Api solution directly.

 

The weird part is that if you do not have the files in the root folder, you still get the CACHED Layout page.

The good part is that when you PUBLISH the solution, it flattens the solution so the VIEWS are in ROOT folder.

 

[Solution]

The solution seems to be in the Startup.cs folder.

Got my solution from here: https://stackoverflow.com/q/50934768/249895

//https://stackoverflow.com/q/50934768/249895
     services.Configure<Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions>(o => {
                o.ViewLocationFormats.Add("/Views/{0}" + Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.ViewExtension);
                o.FileProviders.Add(new Microsoft.Extensions.FileProviders.PhysicalFileProvider(AppContext.BaseDirectory));
            });

After this, you can put your code like this:

var contentRootPath = _hostingEnvironment.ContentRootPath;
string executingAssemblyDirectoryAbsolutePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string executingAssemblyDirectoryRelativePath = System.IO.Path.GetRelativePath(contentRootPath, executingAssemblyDirectoryAbsolutePath);

string executingFilePath = $"{executingAssemblyDirectoryAbsolutePath.Replace('\\', '/')}/Views/Main.cshtml";
string viewPath = "~/Views/Main.cshtml";
string mainViewRelativePath = $"~/{executingAssemblyDirectoryRelativePath.Replace('\\','/')}/Views/Main.cshtml";

var getViewResult = _viewEngine.GetView(executingFilePath: executingFilePath, viewPath: viewPath, isMainPage: true);

<!-- OR -->

var getViewResult = _viewEngine.GetView(executingFilePath: viewPath, viewPath: viewPath, isMainPage: true);

Getting relative path to `bin\Debug\netcoreapp2.2` in ASP.NET Core 2

If you need the relative path of the executing assemblies, you will probably need something like this: ‘~\bin\Debug\netcoreapp2.2’

 

I recently had to do this because I had to render a razor view in an ASP.NET Core 2 application.

Tutorial here: https://scottsauber.com/2018/07/07/walkthrough-creating-an-html-email-template-with-razor-and-razor-class-libraries-and-rendering-it-from-a-net-standard-class-library/

Issue was that I had  to overcome a bug(https://stackoverflow.com/a/56504181/249895) that needed the relative netcodeapp2.2 that the asemblied resided in.

Example:

var viewPath = ‘~/bin/Debug/netcoreapp2.2/Views/MainView.cshtml’;

_viewEngine.GetView(executingFilePath: viewPath , viewPath: viewPath , isMainPage: true);

Getting the `bin\Debug\netcoreapp2.2` can be achieved by using this code:

 

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
public class RenderingService : IRenderingService
{
        
	private readonly IHostingEnvironment _hostingEnvironment;
	public RenderingService(IHostingEnvironment hostingEnvironment)
	{
	_hostingEnvironment = hostingEnvironment;
	}

	public string RelativeAssemblyDirectory()
	{
		var contentRootPath = _hostingEnvironment.ContentRootPath;
		string executingAssemblyDirectoryAbsolutePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
		string executingAssemblyDirectoryRelativePath = System.IO.Path.GetRelativePath(contentRootPath, executingAssemblyDirectoryAbsolutePath);
		return executingAssemblyDirectoryRelativePath;
	}
}

Code Beautifier: http://hilite.me/