52
votes

So I edited my csproj file on an MVC 3 RTM application to set the following property:

<MvcBuildViews>true</MvcBuildViews>

This should cause my views to be complied during build and force a build error if my view is broken. This is the only change I made, however, when I try to build the application, I get the following error:

It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.

The project compiles and runs successfully if I change back to false,

The following are the build tasks configured in the csproj file (these were never manually edited, they were added by Visual Studio 2010)

<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target> -->
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>

Am I missing something here? How do I get MVC 3 / Visual Studio 2010 configured correctly to validate my views at build time?

6
Your web.config has some invalid section defined in it. It's unfortunate the error message does not provide any details. Do you have anything suspicious in web.config?marcind

6 Answers

54
votes

I had this problem a few days ago and I fixed it by deleting obj/Debug folder. Cleaning the project also works. I have no idea about the cause of the issue, though.

See Joe Cartano's answer for a more permanent solution.

38
votes

This problem occurs when there is web project output (templated web.config or temporary publish files) in the obj folder. The ASP.NET compiler used isn't smart enough to ignore stuff in the obj folder, so it throws errors instead.

Another fix is to nuke the publish output right before calling <AspNetCompiler>. Open your .csproj and change this:

<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>

to this:

<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
  <ItemGroup>
    <ExtraWebConfigs Include="$(BaseIntermediateOutputPath)\**\web.config" />
    <ExtraPackageTmp Include="$([System.IO.Directory]::GetDirectories(&quot;$(BaseIntermediateOutputPath)&quot;, &quot;PackageTmp&quot;, System.IO.SearchOption.AllDirectories))" />
  </ItemGroup>
  <Delete Files="@(ExtraWebConfigs)" />
  <RemoveDir Directories="@(ExtraPackageTmp)" />
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>

That will delete all web.configs under \obj, as well as all PackageTmp folders under \obj.

UPDATE:

Even better, based off https://stackoverflow.com/a/48582282/8037 you can exclude the obj folder entirely. Apparently the <AspNetCompiler /> task doesn't have an exclude parameter, but if you switch to calling the aspnet_compiler .exe directly, you can exclude obj like this:

<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
    <Exec Command="$(MSBuildFrameworkToolsPath)aspnet_compiler.exe -v temp -p $(WebProjectOutputDir) -x $(BaseIntermediateOutputPath)"/>
</Target>
22
votes

When you get this error do you have another web.config file in your obj folder? If you are using MSDeploy this might help: http://blogs.msdn.com/b/webdevtools/archive/2010/05/14/the-aspnet-compiler-build-task-in-visual-studio-2010-asp-net-mvc-2-projects.aspx, if not, maybe another web.config is being generated by some tool you are running.

4
votes

This is what worked for me. Optionally, you may specify a condition with the configuration.

<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>
<Target Name="AfterBuild" Condition="'$(Configuration)'!='Debug'">
  <RemoveDir Directories="$(BaseIntermediateOutputPath)" />
</Target>
2
votes

This issue of Compile-time View Checking even though MvcBuildViews is set to 'true' is well-explained in the following MSDN blog:

https://blogs.msdn.microsoft.com/jimlamb/2010/04/20/turn-on-compile-time-view-checking-for-asp-net-mvc-projects-in-tfs-build-2010/

You could do the fix by editing .csproj file directly:

<PropertyGroup>
   <MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>

 <Target Name="BuildViews" Condition="'$(MvcBuildViews)'=='true'" AfterTargets="Build">
   <Message Importance="normal" Text="Precompiling views" />
   <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
 </Target>
2
votes

A simple solution kinda compiled from the other answers here

You can simply remove the whole /obj folder like this:

<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
    <RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" /> <!--add this line-->
    <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>