Razor page can't see referenced class library

2019-02-16 06:36发布

问题:

I started a new MVC Web Application project for the RC2 release and I'm trying to add a class library as a project reference.

I added a simple class library to my project and referenced it and got the following in the project.json file:

"frameworks": {
  "net452": {
    "dependencies": {
      "MyClassLibrary": {
        "target": "project"
      }
    }
  }
},

I can use this library in any of the Controllers and the Startup.cs files without any trouble but I get the following error at run time when I try and use the library from a Razor page:

The name 'MyClassLibrary' does not exist in the current context Output.WriteLine(MyClassLibrary.MyStaticClass.SomeStaticString);

It's weird because I'm getting intellisense for the class library when I'm editing the Razor page, and I can't find anything that says you can't use project references from here.

I thought it was hard enough getting this running under RC1 with the "wrap folder" in the class library project but this has me stumped.

回答1:

A workaround has been posted on the issue page (cred to pranavkm and patrikwlund) https://github.com/aspnet/Razor/issues/755

Apparently you need to explicitly add references to Razor compilation using RazorViewEngineOptions.CompilationCallback.

Add the following to your ConfigureServices method in your Startup class:

var myAssemblies = AppDomain.CurrentDomain.GetAssemblies().Select(x => MetadataReference.CreateFromFile(x.Location)).ToList();

services.Configure((RazorViewEngineOptions options) =>
{
    var previous = options.CompilationCallback;
    options.CompilationCallback = (context) =>
    {
        previous?.Invoke(context);

        context.Compilation = context.Compilation.AddReferences(myAssemblies);
    };
});


回答2:

I had to filter out dynamic assemblies to avoid this runtime exception: The invoked member is not supported in a dynamic assembly.

This worked for me:

var myAssemblies = AppDomain.CurrentDomain.GetAssemblies()
    .Where(x => !x.IsDynamic)
    .Select(x => Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(x.Location))
    .ToList();
services.Configure((Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions options) => {
     var previous = options.CompilationCallback;
     options.CompilationCallback = (context) => {
         previous?.Invoke(context);
         context.Compilation = context.Compilation.AddReferences(myAssemblies);
     };
});