2009-04-16 22 views
60

ho aggiornato da ASP.NET MVC beta di 1,0 e ha fatto le seguenti modifiche al progetto MVC (nel modo descritto nella note di rilascio RC):ASP.NET MVC 1.0 Visualizzazioni AfterBuilding non riesce a TFS costruire

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

Mentre la build funziona bene sulle nostre scatole dev locali, fallisce sotto TFS 2008 build with "Impossibile caricare il tipo 'xxx.MvcApplication'", vedi sotto log di compilazione:

... 
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 è installato TFS e la soluzione viene compilata quando viene creata all'interno di un'istanza di Visual Studio sullo stesso server TFS.

Come posso risolvere questo problema TFS Build?

risposta

17

Il problema deriva dal fatto che l'attività AspNetCompiler MSBuild utilizzata nella destinazione AfterBuild di un progetto ASP.NET MVC prevede di fare riferimento alle DLL nella cartella bin del progetto Web.

Su un desktop, la cartella bin è dove ci si aspetterebbe dall'albero di origine.

Tuttavia TFS Teambuild compila l'output della sorgente in una directory diversa sul server di generazione. Quando l'attività AspNetCompiler viene avviata, non riesce a trovare la directory bin per fare riferimento alla DLL richiesta e si ottiene l'eccezione.

soluzione è quella di modificare il target AfterBuild del progetto MVC di essere come segue:

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

Questa modifica consente di compilare Visualizzazioni sia sul desktop e il TFS costruire server.

+0

che ha funzionato. Spero che MS modifichi il modello di file .csproj di conseguenza. –

+0

questo è pazzesco perché non hanno risolto questo !! ?? –

+0

Controllerò con il team TFS TeamBuild, ma non sono sicuro di poterlo "aggiustare". Questa risposta codifica una struttura di directory specifica per TFS "_PublishedWebsites". Cosa succede se non stai usando TFS TeamBuild per costruire il tuo sito ma usando qualcos'altro? Probabilmente si romperebbe. Spostando questa build in TFS Team Build, hai personalizzato il tuo progetto. Dovrai aggiornare di conseguenza i percorsi, che è ciò che ha fatto la persona che ha risposto a questa domanda. – Haacked

-6

Non è possibile pre-compilare un'applicazione ASP.NET MVC.

+0

Vedere risposta di Jim Lamb per la soluzione corretta. –

1

presumo che significava che si modifica l'impostazione seguente nel file Csproj:

<MvcBuildViews>true</MvcBuildViews> 

L'impostazione che hai postato nella tua domanda non deve essere toccato. Se funziona sul computer locale, ovviamente è possibile pre-compilare un'applicazione ASP.NET MVC.

Penso che sia necessario rintracciare le differenze tra l'ambiente di costruzione TFS e le macchine VS locali. Forse sta usando una versione diversa di MsBuild o qualcosa del genere.

Provare ad eseguire entrambe le build con output dettagliato e confrontare i due per vedere cosa è diverso.

+0

I percorsi utilizzati in TFS sono completamente diversi da quelli sul mio computer locale e nel controllo del codice sorgente, pertanto è necessario specificare posizioni diverse per ogni scenario. – Leather

+0

@haacked come mai questo non è mai stato aggiornato nel template? è piuttosto confuso la prima volta che ci si imbatte in esso. in particolare tutti quei nuovi utenti di "TFS Basic" non abituati a gestire cose come questa –

0

Stiamo ancora testando questo, ma sembra che sia possibile spostare il falso/vero dal set di tag, nel gruppo di proprietà per la versione di build DEBUG, è ancora possibile impostarlo su true e MSBuild verrà compilato (assumendo Il file MSBuild TfsBuild.proj è configurato per utilizzare qualcosa di diverso dalla configurazione di debug). Sarà necessario modificare il file csproj utilizzando Blocco note per realizzare questo.

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

è necessario spostare il tag MVCBuildViews dal gruppo di proprietà di default sopra, per il gruppo di proprietà di configurazione di debug (in basso). Di nuovo, quando avremo il setup TFS/MSBuild, proverò a postare il passo che abbiamo aggiunto al nostro file TFSBuild.proj in TFS.

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

La risposta accettata non ha funzionato per me. Il parametro $ (PublishDir) non puntava alla posizione corretta. Invece ho dovuto usare:

<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

Benché la risposta ti abbia indirizzato nella giusta direzione, va tutto bene. OutDir sul mio setup punta a una directory di root build che contiene tutti gli assembly degli altri progetti all'interno della soluzione, PublishDir punta ai progetti di applicazione Web contenuti nella soluzione. La tua soluzione contiene altri progetti oltre alla MVC Web App? – crowleym

+0

Sì, contiene più progetti e sì, la tua risposta mi ha indirizzato nella giusta direzione. Non sono sicuro del perché il $ PublishDir funzioni per te e non per me, ma non ne sono troppo incasinato, la correzione è semplice e ho pensato di inserirla lì se qualcuno si fosse imbattuto nello stesso problema . –

178

In realtà, c'è una soluzione migliore a questo problema. Ho provato con VS/TFS 2010, ma dovrebbe funzionare anche con VS/TFS 2008.

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

ho intenzione di lavorare con il team di MVC di aggiornare il proprio modello di progetto da utilizzare per questo approccio insieme un target personalizzato (piuttosto che sostituire AfterBuild).

Ho pubblicato un post sul blog su Turn on Compile-time View Checking for ASP.NET MVC projects in TFS Build 2010.

+0

E se la tua soluzione contiene più di un progetto web, come funzionerà? Ecco perché ho costruito il percorso da solo ... – crowleym

+1

Dovrebbe funzionare bene con più progetti Web - WebProjectOutputDir è distinto per ogni progetto. –

+0

che funziona davvero! soluzione bella e pulita –

0

Nel mio controllo sorgente avevo alcune vecchie cartelle che non erano visibili nella Soluzione.

3

soluzione di Jim Lamb non ha funzionato per noi quando ho costruito la nostra Csproj web con

/p:UseWPP_CopyWebApplication=true;PipelineDependsOnBuild=False 

perché l'obiettivo è stato in esecuzione AfterBuild e l'applicazione non è stato copiato nel WebProjectOutputDir ancora. (BTW, ho passato tali proprietà al progetto web build cos voglio che la build crei una cartella OutDir con solo i miei binari e file cshtml adatti per zippare, cioè non una build sul posto)

Per aggirare questo problema e onorare l'intento del suo obiettivo originale, ho fatto quanto segue:

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

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