问题
My solution consist of 2 projects:
- MyApp.Rest
- MyApp.Core
Core uses Razor templating to generate emails and reports. Rest is a WebAPI only and references Core. Rest has the startup file, where Razor configuration takes place. Core will also be used by other projects in the future.
The problem is I am not able to make the view engine to locate view files even though I have added the output directory as a FileProvider for razor and the template has been copied to the output directory.
Output Directory:
MyApp.Code.dll
MyApp.Rest.dll
RazorTemplates
-> Template1.cshtml
Startup.cs
services.AddMvc()
.AddApplicationPart(typeof(MyApp.Core.RazorViewRenderer).GetTypeInfo().Assembly)
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
services.Configure<RazorViewEngineOptions>(o => {
o.ViewLocationFormats.Add("/RazorTemplates/{0}" + RazorViewEngine.ViewExtension);
o.FileProviders.Add(new PhysicalFileProvider(AppContext.BaseDirectory));
});
RazorViewRenderer.cs:
public async Task<string> RenderAsync<TModel>(string name, TModel model) {
var actionContext = GetDefaultActionContext();
var viewEngineResult = _viewEngine.FindView(actionContext, "Template1", true);
if (!viewEngineResult.Success) {
throw new InvalidOperationException($"View '{name}' cannot be found."); //Craches here.
}
var view = viewEngineResult.View;
using (var output = new StringWriter()) {
var viewContext = new ViewContext(actionContext, view,
new ViewDataDictionary<TModel>(
metadataProvider: new EmptyModelMetadataProvider(),
modelState: new ModelStateDictionary()) {
Model = model
},
new TempDataDictionary(
actionContext.HttpContext,
_tempDataProvider),
output,
new HtmlHelperOptions());
await view.RenderAsync(viewContext);
return output.ToString();
}
}
Note: RazorLight is not an option. It does not support Html helpers and it does not support localization at all.
回答1:
Solved my problem using GetView() instead of FindView().
Also, localization was broken. I had to use my own implementation of IViewLocalizer since looking at Microsoft's code on GitHub, IViewLocalizer uses the assembly specified in IHostingEnvironment, which was set to MyApp.Rest instead of MyApp.Core.
回答2:
You have to add all child folder path
o.ViewLocationFormats.Add("/Views/RazorTemplates/{0}.cshtml");
来源:https://stackoverflow.com/questions/50934768/cannot-find-view-located-in-referenced-project