Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Razor compilation should print a meaningful error when ref assemblies cannot be found. #6283

Closed
tverboon opened this issue May 17, 2017 · 9 comments
Assignees
Labels

Comments

@tverboon
Copy link

tverboon commented May 17, 2017

We have enabled MvcRazorCompileOnPublish in our web projects in 2.0.0-preview-1. We publish and run it in a Docker container and we got the following error:

InvalidOperationException: Cannot find compilation library location for package 'Microsoft.Win32.Registry'
Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths()

After a lot of eliminating we found out it were views in a shared library. The solution was to add:
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>

Other error, but same issue as: #6021 and possibly #6178.

I just report it, so people can find this issue when they encounter this exception, which is also mentioned in: https://github.com/dotnet/core-setup/issues/2113

@tverboon tverboon changed the title Pre-compiled views in shared library in Docker container: InvalidOperationException: Cannot find compilation library location for package 'Microsoft.Win32.Registry' Pre-compiled views and views in shared library in Docker container: InvalidOperationException: Cannot find compilation library location for package 'Microsoft.Win32.Registry' May 17, 2017
@pranavkm
Copy link
Contributor

After a lot of eliminating we found out it were views in a shared library.

Did the library have embedded views?

@tverboon
Copy link
Author

Yes, sorry, that is what I meant. A library with embedded views. Some common Display and editor templates we use across projects.

@pranavkm pranavkm self-assigned this Jul 24, 2017
@pranavkm pranavkm added this to the 2.1.0 milestone Jul 24, 2017
@pranavkm
Copy link
Contributor

@tverboon https://github.com/dotnet/core-setup/issues/2113 was closed a while ago. Have you had a chance to try this with the preview2 bits and see if this continues to be an issue?

@tverboon
Copy link
Author

Precompiling views in a shared assembly will still throw this exception without <MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish> in the web project.

The only 'issue' is that the error isn't very clear about what the problem is and how to fix it. What is package Microsoft.Win32.Registry? And why is it needed in a Linux Docker container? That were questions I had when I saw the error.

The solution, you already provided, to fix this exception is: #6021 (comment)

I guess this issue can be closed, unless you want to throw a more specific exception if that's possible anyway.

@pranavkm pranavkm changed the title Pre-compiled views and views in shared library in Docker container: InvalidOperationException: Cannot find compilation library location for package 'Microsoft.Win32.Registry' Razor compilation should print a meaningful error when ref assemblies cannot be found. Jul 25, 2017
@pranavkm
Copy link
Contributor

I guess we've regressed this issue (#4202). I'll use this issue to see if we can revive the error.

@tverboon
Copy link
Author

@pranavkm I precompiled the views in the shared assembly and output them to the publish directory as you suggested in #6021 (comment).

Very simple actually with MSBuild:

<Target Name="PublishSharedViews" AfterTargets="PrepareForPublish" >
    <MSBuild Projects="$(ProjectDir)../Common.Web/Common.Web.csproj" Targets="Publish" Properties="MvcRazorOutputPath=$([System.IO.Path]::GetFullPath('$(PublishDir)'))" />
</Target>

The Common.Web.PrecompiledViews.dll is in the publish output directory.

But I still have to set the property to prevent the exception:

<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>

Is this right? In your comment you write:

There's two ways to fix this

  • Stick false in your csproj. This should continue publishing the refs directory as part of the publish output.
  • You could precompile the views in the class library.

I was reading this as one or the other. I am still under the impression that the shared views are compiled at runtime when I set the MvcRazorExcludeRefAssembliesFromPublish to false, even though I published the Common.Web.PrecompiledViews.dll.

Is there a way for me to see if a view is compiled the first time, other than a slower response?

@pranavkm
Copy link
Contributor

I am still under the impression that the shared views are compiled at runtime

The precompiled views should replace runtime compiled views if it's referenced correctly. Does your Mvc reference the ClassLibrary or is it simply dropped in? In the former case, it becomes an ApplicationPart and participates in precompiled view discovery. Also, one way to tell if those views are discovered correctly is by doing this in an action:

public string GetPrecompiledResourceNames([FromServices] ApplicationPartManager applicationManager)
{
    var feature = new ViewsFeature();
    applicationManager.PopulateFeature(feature);
    return string.Join(Environment.NewLine, feature.ViewDescriptors.Select(v => v.RelativePath));
}

@tverboon
Copy link
Author

The views weren't discovered, although the Common.Web.PrecompiledViews.dll was found and loaded by PopulateFeature. Eventually the problem was the Common.Web assembly was of project type <Project Sdk="Microsoft.NET.Sdk"> instead of <Project Sdk="Microsoft.NET.Sdk.Web">. Thank you! It works great now.

@pranavkm pranavkm reopened this Aug 14, 2017
@pranavkm
Copy link
Contributor

I was mistaken, we haven't regressed the feature. The exception continues to have a message about using the sdk or setting PreserveCompilationContext. We should be good to close this since there's nothing more to do here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants