Cannot find view located in referenced project
Asked Answered
S

2

1

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.

Skimp answered 19/6, 2018 at 18:24 Comment(2)
Did you tried using AddApplicationParts ?Setup
Yes. I updated my code accordingly. I have checked with Process Monitor and Razor doesn't event try to look for a cshtml file. Also, viewEngineResult.SearchedLocations is empty, even though RazorViewEngineOptions.ViewLocationFormats is not.Skimp
S
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.

Skimp answered 19/6, 2018 at 20:45 Comment(0)
G
-2

You have to add all child folder path

o.ViewLocationFormats.Add("/Views/RazorTemplates/{0}.cshtml");
Grout answered 20/6, 2018 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.