ASP.NET MVC 1.0 AfterBuilding视图在TFS Build上失败

时间:2009-04-16 11:07:01

标签: asp.net asp.net-mvc tfsbuild

我已从ASP.NET MVC Beta升级到1.0并对MVC项目进行了以下更改(如RC发行说明中所述):

<Project ...>
  ...
  <MvcBuildViews>true</MvcBuildViews>
  ...
  <Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
    <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
  </Target>
  ...
</Project>

虽然构建在我们的本地开发盒上运行良好,但它在TFS 2008 Build下失败,“无法加载类型'xxx.MvcApplication'”,请参见下面的构建日志:

...
using "AspNetCompiler" task from assembly "Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "AspNetCompiler"

  Command:
  C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe -v temp -p D:\Builds\xxx\Continuous\TeamBuild\Sources\UI\xxx.UI.Dashboard\\..\xxx.UI.Dashboard 
  The "AspNetCompiler" task is using "aspnet_compiler.exe" from "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe".
  Utility to precompile an ASP.NET application
  Copyright (C) Microsoft Corporation. All rights reserved.

/temp/global.asax(1): error ASPPARSE: Could not load type 'xxx.UI.Dashboard.MvcApplication'.
  The command exited with code 1.

Done executing task "AspNetCompiler" -- FAILED.
...

MVC上安装了MVC 1.0,并且该解决方案在同一TFS服务器上的Visual Studio实例中构建时进行编译。

如何解决此TFS Build问题?

9 个答案:

答案 0 :(得分:179)

实际上,这个问题有一个更好的解决方案。我已经使用VS / TFS 2010对其进行了测试,但它也适用于VS / TFS 2008。

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

我将与MVC团队合作更新他们的项目模板,以便将此方法与自定义目标一起使用(而不是覆盖AfterBuild)。

我发布了一篇关于如何Turn on Compile-time View Checking for ASP.NET MVC projects in TFS Build 2010的博客文章。

答案 1 :(得分:17)

问题源于ASP.NET MVC项目的AfterBuild目标中使用的AspNetCompiler MSBuild任务需要引用Web项目的bin文件夹中的dll。

在桌面构建中,bin文件夹位于源树下的预期位置。

但是,TFS Teambuild会将源的输出编译到构建服务器上的其他目录。当AspNetCompiler任务启动时,它找不到bin目录来引用所需的DLL,并且你得到了异常。

解决方案是将MVC项目的AfterBuild目标修改为如下:

  <Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
    <AspNetCompiler Condition="'$(IsDesktopBuild)' != 'false'" VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
    <AspNetCompiler Condition="'$(IsDesktopBuild)' == 'false'" VirtualPath="temp" PhysicalPath="$(PublishDir)\_PublishedWebsites\$(ProjectName)" />
  </Target>

此更改使您可以在桌面和TFS构建服务器上编译视图。

答案 2 :(得分:3)

当我使用

构建我们的网站.csproj时,Jim Lamb的解决方案对我们不起作用
/p:UseWPP_CopyWebApplication=true;PipelineDependsOnBuild=False

因为目标正在执行AfterBuild并且应用程序尚未复制到WebProjectOutputDir。 (顺便说一句,我将这些属性传递给web项目构建我希望构建创建一个OutDir文件夹,只包含我的二进制文件和适合压缩的cshtml文件,即不是就地构建)

为了解决这个问题并尊重他原定目标的意图,我做了以下事情:

<PropertyGroup>
    <OnAfter_WPPCopyWebApplication>
        MvcBuildViews;
    </OnAfter_WPPCopyWebApplication>
</PropertyGroup>

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

答案 3 :(得分:1)

我认为您的意思是更改了.csproj文件中的以下设置:

<MvcBuildViews>true</MvcBuildViews>

不应触及您在问题中发布的设置。 如果它适用于您的本地计算机,那么显然您可以预构建ASP.NET MVC应用程序。

我认为您需要找出TFS构建环境与本地VS计算机之间的不同之处。也许它正在使用不同版本的MsBuild或其他东西。

尝试使用详细输出执行两个构建并比较两者以查看不同的内容。

答案 4 :(得分:0)

我们仍然在测试它,但看起来您可以将false / true从标记集移动到DEBUG构建版本的属性组中,您仍然可以将其设置为true并且MSBuild将编译(假设MSBuild) TfsBuild.proj文件设置为使用除调试配置之外的其他内容)。您需要使用记事本编辑csproj文件才能完成此操作。

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <MvcBuildViews>true</MvcBuildViews>
    ....

您需要将MVCBuildViews标记从上面的默认属性组移动到调试配置属性组(如下所示)。再次,当我们获得TFS / MSBuild设置时,我将尝试将我们添加的步骤发布到TFS中的TFSBuild.proj文件中。

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <MvcBuildViews>true</MvcBuildViews>
    <DebugSymbols>true</DebugSymbols>
    ....

答案 5 :(得分:0)

这个问题与这里谈到的问题类似: http://blogs.msdn.com/aaronhallberg/archive/2007/07/02/team-build-and-web-deployment-projects.aspx 似乎aspnet_compiler.exe的调用无法找到二进制文件,因为它不在构建机器上的MVC项目的bin文件夹中。我还没有找到解决方案。

答案 6 :(得分:0)

接受的答案对我不起作用。 $(PublishDir)参数未指向正确的位置。相反,我不得不使用:

  <Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
    <AspNetCompiler Condition="'$(IsDesktopBuild)' != 'false'" VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
    <AspNetCompiler Condition="'$(IsDesktopBuild)' == 'false'" VirtualPath="temp" PhysicalPath="$(OutDir)\_PublishedWebsites\$(ProjectName)" />
  </Target>

答案 7 :(得分:0)

我的源代码管理中有一些旧文件夹在解决方案中不可见。

答案 8 :(得分:-6)

您无法预构建ASP.NET MVC应用程序。