7

In my Asp.Net MVC 4 project, I've set in the .csproj file to build the view <MvcBuildViews>true</MvcBuildViews>. The problem is that building the project I got the 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.

I tried to delete the obj folder but the error keep raising. The error specify that the problem is in the authentication tag row:

<system.web>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="2880" />
    </authentication>

Often, I'm able to run the application by running the application (I got the error), building the app and after that running again.

Darion Badlydone
  • 897
  • 14
  • 37

3 Answers3

10

Doing what @matrixugly suggests will fix the issue, but will also cause the compile-time view checking to stop working as well. I am assuming you still want to error check your views at compile time? If that is the case, better fixes below.

In order to understand why these solutions work, we have to first know how the problem is created:

  1. The developer wants compile-time checking on views, so they set MvcBuildViews=true.
  2. The application builds fine, UNTIL they publish the project.
  3. Subsequent attempts to build the project result in a compile-time 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.

So what causes this issue? When the project is published the compiler, by default it uses <project-dir>\obj\ to place copies of the source files that it will work with. Unfortunately, these files are not automatically deleted when publishing is complete. The next time the developer compiles the project with MvcBuildViews=true, it will error out because the aspnet compiler includes the obj\ folder during compilation, since it is underneath the <project-dir> folder.

So how do we fix this? Well, you have four options:

  1. Set MvcBuildViews=false. I don't really consider this a solution, so let's move on.
  2. Delete the files in <project-dir>\obj\. Works, but can be a hassle since it has to be done after every publish.
  3. Change the path that publishing uses as an intermediate directory through the use of the <BaseIntermediateOutputPath> property in your project config file.

    Example (Ref: this link):

    <BaseIntermediateOutputPath> [SomeKnownLocationIHaveAccessTo] </BaseIntermediateOutputPath>

  4. Add a new section in your project config file that deletes the offending files for you on build (reference Microsoft Connect). I've even made it easy for you, just copy and paste:

    <PropertyGroup>
    <_EnableCleanOnBuildForMvcViews Condition=" '$(_EnableCleanOnBuildForMvcViews)'=='' ">true</_EnableCleanOnBuildForMvcViews>
    </PropertyGroup>
    <Target Name="CleanupForBuildMvcViews" Condition=" '$(_EnableCleanOnBuildForMvcViews)'=='true' and '$(MVCBuildViews)'=='true' " BeforeTargets="MvcBuildViews">
    <ItemGroup>
        <_TempWebConfigToDelete Include="$(BaseIntermediateOutputPath)**\Package\**\*" />
        <_TempWebConfigToDelete Include="$(BaseIntermediateOutputPath)**\TransformWebConfig\**\*" />
        <_TempWebConfigToDelete Include="$(BaseIntermediateOutputPath)**\CSAutoParameterize\**\*" />
        <_TempWebConfigToDelete Include="$(BaseIntermediateOutputPath)**\TempPE\**\*" />
    </ItemGroup>
    
    <Delete Files="@(_TempWebConfigToDelete)"/>
    </Target>
    

My recommendation would be to use either option 3 or 4.

N.B. For those that have never edited their project file, you can't edit it while loaded. It must first be unloaded by right clicking it and selecting Unload Project. You can then right-click the project and edit the project file. Alternatively, you can edit the file outside of Visual Studio.

newmanth
  • 408
  • 7
  • 18
0

I had the exact same problem when trying to publish my web application after enabling MvcBuildViews to validate my Razor syntax

I found this code in my web config

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

Try commenting it out, so that the compiler behavior is not changed

  <!--<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>-->
C. Tewalt
  • 2,271
  • 2
  • 30
  • 49
  • if you are going to downvote an answer that's almost 4 years old, please leave a comment, thanks ;) – C. Tewalt Jun 01 '18 at 13:40
  • This doesn't address the issue. But if you want to disable `MvcBuildViews`, then in your .csproj, within `PropertyGroup`, add this: `False` (Or perhaps .pubxml publishing profile overrides that, then set it there) And you didn't find this in your web.config, but some .target file on your filesystem, which will probably get overwritten with some msbuild updates. – Janis Veinbergs Mar 03 '22 at 15:36
0

@newmanth answer is excellent, but outdated. Year 2022 and let me tell you - this CleanupForBuildMvcViews is actually oficially included within C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Microsoft\VisualStudio\v16.0\Web\Microsoft.Web.Publishing.targets! :)

It even features the link to (now broken) Microsoft Connect as @newmanth references.

Here is the snippet:

  <!--Deal with http://connect.microsoft.com/VisualStudio/feedback/details/779737/error-allowdefinition-machinetoapplication-beyond-application-level, 
  we will need to clean up our temp folder before MVC project starts the pre-compile-->
  <PropertyGroup>
    <_EnableCleanOnBuildForMvcViews Condition=" '$(_EnableCleanOnBuildForMvcViews)'=='' ">true</_EnableCleanOnBuildForMvcViews>
  </PropertyGroup>
  <Target Name="CleanupForBuildMvcViews" Condition=" '$(_EnableCleanOnBuildForMvcViews)'=='true' and '$(MVCBuildViews)'=='true' " BeforeTargets="MvcBuildViews">
    <ItemGroup>
      <_PublishTempFolderNamesToCleanup Include="Database;TransformWebConfig;CSAutoParameterize;InsertAdditionalCS;ProfileTransformWebConfig;Package" />
    </ItemGroup>
    <!--Force msbuild to expand all the wildcard characters so to get real file paths-->
    <CreateItem Include="@(_PublishTempFolderNamesToCleanup->'$(BaseIntermediateOutputPath)**\%(identity)\**\*')">
      <Output TaskParameter="Include" ItemName="_EvaluatedPublishTempFolderNamesToCleanup" />
    </CreateItem>
    <Delete Files="@(_EvaluatedPublishTempFolderNamesToCleanup)" />
  </Target>

However I still get the said exception. In my Case I had to delete AspnetCompileMerge folder too. And name Target in another name, not to overwrite it:

  <PropertyGroup>
    <_EnableCleanOnBuildForMvcViews Condition=" '$(_EnableCleanOnBuildForMvcViews)'=='' ">true</_EnableCleanOnBuildForMvcViews>
  </PropertyGroup>
  <Target Name="CleanupForBuildMvcViews2" Condition=" '$(_EnableCleanOnBuildForMvcViews)'=='true' and '$(MVCBuildViews)'=='true' " BeforeTargets="MvcBuildViews">
    <ItemGroup>
        <_TempWebConfigToDelete Include="$(BaseIntermediateOutputPath)**\AspnetCompileMerge\**\*" />
    </ItemGroup>
    <Delete Files="@(_TempWebConfigToDelete)"/>
  </Target>
Janis Veinbergs
  • 6,907
  • 5
  • 48
  • 78