2009-04-16 14 views
60

He actualizado desde ASP.NET MVC Beta a 1,0 e hice los siguientes cambios en el proyecto MVC (según lo expuesto en las notas de la versión RC):ASP.NET MVC 1.0 AfterBuilding Vistas falla en TFS Build

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

Mientras que la acumulación funciona muy bien en nuestras cajas dev locales, se produce un error en TFS 2008 Build con "no se pudo cargar el tipo 'xxx.MvcApplication'", ver más abajo registro de generación:

... 
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 1.0 está instalado en TFS y la solución se compila cuando se genera dentro de una instancia de Visual Studio en el mismo servidor TFS.

¿Cómo puedo resolver este problema de compilación de TFS?

Respuesta

17

El problema se debe al hecho de que la tarea AspNetCompiler MSBuild utilizada dentro del objetivo AfterBuild de un proyecto ASP.NET MVC espera hacer referencia a los dll en la carpeta bin del proyecto web.

En una compilación de escritorio, la carpeta bin está donde lo esperaría en su árbol fuente.

Sin embargo, TFS Teambuild compila la salida de su fuente a un directorio diferente en el servidor de compilación. Cuando se inicia la tarea AspNetCompiler, no puede encontrar el directorio bin para hacer referencia a la DLL requerida y se obtiene la excepción.

solución es modificar el objetivo AfterBuild del Proyecto MVC ser de la siguiente manera:

<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> 

Este cambio le permite compilar Vistas tanto en el escritorio, y el TFS construir servidor.

+0

Eso funcionó. Hope MS cambia la plantilla de archivo .csproj en consecuencia. –

+0

eso es una locura, ¿por qué no han solucionado esto? ?? –

+0

Lo consultaré con el equipo de TFS TeamBuild, pero no estoy seguro de si podemos "arreglarlo". Esta respuesta codifica una estructura de directorio específica de TFS "_PublishedWebsites". ¿Qué sucede si no está utilizando TFS TeamBuild para construir su sitio pero usando algo más? Eso probablemente se rompa. Al mover esta compilación a TFS Team Build, ha personalizado su proyecto. Deberá actualizar las rutas en consecuencia, que es lo que hizo la persona que respondió esta pregunta. – Haacked

-6

No se puede precompilar una aplicación ASP.NET MVC.

+0

Consulte la respuesta de Jim Lamb para la solución correcta. –

1

supongo que quería decir que ha cambiado la siguiente configuración en el archivo .csproj:

<MvcBuildViews>true</MvcBuildViews> 

El ajuste que ha escrito en su pregunta no debe ser tocada. Si funciona en su máquina local, entonces obviamente puede precompilar una aplicación ASP.NET MVC.

Creo que debe rastrear qué es diferente entre su entorno de construcción TFS y sus máquinas VS locales. Tal vez esté usando una versión diferente de MsBuild o algo así.

Intente realizar ambas compilaciones con salida detallada y compare las dos para ver qué es diferente.

+0

Las rutas, etc. utilizadas en TFS parecen ser completamente diferentes de las de mi máquina local y en control de fuente, por lo tanto, debe especificar ubicaciones diferentes para cada escenario. – Leather

+0

@haacked ¿cómo es que esto nunca se actualizó en la plantilla? es bastante confuso la primera vez que te topas con eso. especialmente todos aquellos nuevos usuarios de 'TFS Basic' no acostumbrados a tratar con cosas como esta –

0

Todavía estamos probando esto, pero parece que puede mover el falso/verdadero del conjunto de etiquetas, al grupo de propiedades para su versión de compilación DEBUG, todavía puede establecerlo en verdadero y MSBuild compilará (asumiendo El archivo MSBuild TfsBuild.proj está configurado para usar algo que no sea la configuración de depuración). Deberá editar el archivo csproj con el Bloc de notas para lograrlo.

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

tiene que mover la etiqueta MVCBuildViews del grupo propiedad predeterminada anteriormente, para el grupo de propiedades de configuración de depuración (abajo). De nuevo, cuando obtengamos la configuración de TFS/MSBuild, intentaré publicar el paso que añadimos a nuestro archivo TFSBuild.proj en TFS.

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

La respuesta aceptada no funcionó para mí. El parámetro $ (PublishDir) no apuntó a la ubicación correcta. En cambio tuve que usar:

<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> 
+0

Bueno, siempre y cuando la respuesta te haya apuntado en la dirección correcta, entonces todo está bien. OutDir en mi configuración apunta a un directorio de compilación raíz que contiene todos los ensamblados de los otros proyectos dentro de la solución, PublishDir apunta a los proyectos de la Aplicación web contenidos en la solución. ¿Su solución contiene otros proyectos además de la aplicación web MVC? – crowleym

+0

Sí, contiene varios proyectos, y sí, su respuesta me indicó la dirección correcta. No estoy seguro de por qué el $ PublishDir funciona para usted y no yo, pero no estoy demasiado preocupado por él, la solución fue sencilla y pensé que lo pondría allí si alguien más se encuentra con el mismo problema. . –

178

En realidad, hay una mejor solución a este problema. Lo he probado con VS/TFS 2010, pero también debería funcionar con VS/TFS 2008.

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

Voy a trabajar con el equipo de MVC para actualizar su plantilla de proyecto a utilizar este método junto con un objetivo personalizado (en lugar de anular AfterBuild).

He publicado una publicación en el blog sobre cómo Turn on Compile-time View Checking for ASP.NET MVC projects in TFS Build 2010.

+0

Y si su solución contiene más de un proyecto web, ¿cómo funcionará? Es por eso que construí el camino yo mismo ... – crowleym

+1

Debería funcionar bien con múltiples proyectos web: WebProjectOutputDir es distinto para cada proyecto. –

+0

que realmente funciona! solución agradable y limpia –

0

Tenía algunas carpetas antiguas en mi control de fuente que no estaban visibles en la Solución.

3

solución de Jim Lamb no funcionó para nosotros cuando construí nuestra .csproj web con

/p:UseWPP_CopyWebApplication=true;PipelineDependsOnBuild=False 

porque el objetivo se está ejecutando AfterBuild y la aplicación no se ha copiado en el WebProjectOutputDir todavía. (Por cierto, paso esas propiedades a la construcción del proyecto web porque quiero que la compilación cree una carpeta OutDir con solo mis archivos binarios y cshtml adecuados para comprimir, es decir, no una compilación en contexto)

Para solucionar este problema y respete la intención de su objetivo original, hice lo siguiente:

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

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