aspnet/MvcPrecompilation

Precompiled views don't work for relative paths

Closed this issue · 16 comments

On running dotnet publish I get a *.PrecompiledViews.dll and no refs folder.

On running dotnet publish -r win7-x64 I get no *.PrecopmiledViews.dll and a refs folder.

I tried copying the *.PrecompiledViews.dll from one to the other but it didn't work.

@pranavkm, what is the expected behavior here?

Expected: dotnet publish -r win7-x64 should yield *.PrecompiledViews.dll and no refs folder.

We specifically disabled precompilation for self contained apps in 2.0. #102 (comment) has some guidance on what you could do workaround this. The issue is addressed as part of 2.1.0-preview1 release.

That workaround definitely does not work. Excluding the views and providing *.PrecompiledViews.dll just results in "View not found" being spammed to the log file.

Do you have a repro app for this? We've been recommending the copying behavior for a while now and it's worked for most users.

I have an application that reliably reproduces it but I can't publish it here. At this point our team plan is to try the 2.1 version of .NET Core (which will take some effort) before we see if we can reduce this out. I was able to try the workaround quickly because it merely involved copying a few files around.

@pranavkm : I couldn't find an official preview release, and the nightly builds currently ship with an MVC Razor that doesn't work. I filed the bug in core itself because the template mvc project doesn't work. dotnet/core#1221

@jhudsoncedaron, unfortunately we won't be able to help you without a repro. If you could share with us a minimalistic repro project, with all the "sensitive" stuff stripped out, that would be great.

@jhudsoncedaron the issue is a runtime issue. Updating to the most recent Microsoft.AspNetCore.All runtime (https://github.com/aspnet/Universe#daily-builds) should resolve the issue

I'm sorry. I don't actually understand razor views very well and am blundering around. I have successfully determined the following: The workaround doesn't work when the view references another view with '..' in the reference path.

@jhudsoncedaron when you say reference, is this when you're attempting to do something along the lines of Html.Partial("../_Partial") or Layout = "../Layout"? We did have a couple of issues around this that we fixed as part of aspnet/Mvc#6676, but perhaps you're run in to a scenario we didn't fix cover. What does the calling code look like - that should give us something we could help you with.

I constructed a (silly) reproduction from the empty template using Html.Partial.

build project with
dotnet publish
dotnet publish -r win7-x64
cd bin\debug\netcoreapp2.0\win7-x64\publish
mklink emptymvc20.PrecompiledViews.dll ....\publish\emptymvc20.PrecompiledViews.dll
rmdir /s Views

Run with
emptymvc20.exe

Open http://localhost:5000; see that the page loads.
Open http://localhost:5000/T1; see that the page loads.
Open http://localhost:5000/T2; see the error and the long stack trace

cd ..\..\..\..\..
dotnet run

Open http://localhost:5000/T2; see that the page loads.

emptymvc20.zip

Thanks @jhudsoncedaron. I'll have a look.

I tried it on the nightly builds but ASP .NET nightly builds are still broken as of today's build 2.2.0-previwe1-007947 retrieved from https://github.com/dotnet/cli/blob/master/README.md

@jhudsoncedaron, the issue is fixed in 2.1.0-preview1. Here's the change to your csproj you can use to verify the change:

// emptymvc20.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <RestoreSources>https://api.nuget.org/v3/index.json;https://dotnet.myget.org/f/aspnetcore-dev/api/v3/index.json</RestoreSources>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0-preview1-28137" />
  </ItemGroup>

</Project>

For the 2.0 release, here's some past discussion around this area: aspnet/Mvc#6672 (comment). Tl;dr: use @Html.Partial("../T1/Index.cshtml", null). That should cause Mvc to treat it as a path instead of a name and running in to the issue you're running it now.