Implementación web de ASP.NET mediante Visual Studio: implementación de archivos adicionales

por Tom Dykstra

Descarga del proyecto de inicio

Esta serie de tutoriales muestra cómo implementar (publicar) una aplicación web ASP.NET en Azure App Service Web Apps o en un proveedor de hospedaje de terceros mediante Visual Studio 2012 o Visual Studio 2010. Para obtener información sobre la serie de tutoriales, consulte el primer tutorial de la serie.

Información general

En este tutorial se muestra cómo ampliar la canalización de publicación web de Visual Studio para realizar una tarea adicional durante la implementación. La tarea consiste en copiar archivos adicionales que no están en la carpeta del proyecto del sitio web de destino.

Para este tutorial, copiará un archivo adicional: robots.txt. Quiere implementar este archivo en el almacenamiento provisional, pero no en producción. En el tutorial Implementación en producción agregó este archivo al proyecto y configuró el perfil de publicación de producción para excluirlo. En este tutorial verá un método alternativo para controlar esta situación, uno que será útil para los archivos que quiera implementar, pero que no quiere incluirlos en el proyecto.

Mover el archivo robots.txt

Para prepararse para usar un método diferente para controlar robots.txt, en esta sección del tutorial moverá el archivo a una carpeta que no se incluye en el proyecto y eliminará robots.txt del entorno de almacenamiento provisional. Es necesario eliminar el archivo del almacenamiento provisional para que pueda comprobar que el nuevo método de implementación del archivo en ese entorno funciona correctamente.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el archivo robots.txt y haga clic en Excluir del proyecto.

  2. Con el Explorador de archivos de Windows, cree una carpeta en la carpeta de la solución y asígnele el nombre ExtraFiles.

  3. Mueva el archivo robots.txt de la carpeta del proyecto ContosoUniversity a la carpeta ExtraFiles.

    ExtraFiles folder

  4. Con la herramienta FTP, elimine el archivo robots.txt del sitio web de almacenamiento provisional.

    Como alternativa, puede seleccionar Quitar archivos adicionales en el destino, en Opciones de publicación de archivos, en la pestaña Configuración del perfil de publicación de almacenamiento provisional y volver a publicarlo en el almacenamiento provisional.

Actualización del archivo de perfil de publicación

Solo necesita robots.txt en el almacenamiento provisional, por lo que el único perfil de publicación que necesita actualizar para implementarlo es Almacenamiento provisional.

  1. En Visual Studio, abra Staging.pubxml.

  2. Al final del archivo, antes de la etiqueta de cierre </Project>, agregue el marcado siguiente:

    <Target Name="CustomCollectFiles">
        <ItemGroup>
          <_CustomFiles Include="..\ExtraFiles\**\*" />
          <FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
            <DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
          </FilesForPackagingFromProject>
        </ItemGroup>
      </Target>
    

    Este código crea un destino que recopilará archivos adicionales que se van a implementar. Un destino se compone de una o varias tareas que MSBuild ejecutará en función de las condiciones que especifique.

    El atributo Include especifica que la carpeta en la que deben buscarse los archivos es ExtraFiles, que se encuentra en el mismo nivel que la carpeta del proyecto. MSBuild recopilará todos los archivos de esa carpeta y de forma recursiva desde cualquier subcarpeta (el asterisco doble especifica subcarpetas recursivas). Con este código podría colocar varios archivos, y archivos en subcarpetas dentro de la carpeta ExtraFiles, y se implementarían todos.

    El elemento DestinationRelativePath especifica que las carpetas y los archivos se deben copiar en la carpeta raíz del sitio web de destino, en la misma estructura de archivos y carpetas que se encuentran en la carpeta ExtraFiles. Si desea copiar la propia carpeta ExtraFiles, el valor DestinationRelativePath sería ExtraFiles\%(RecursiveDir)%(Filename)%(Extension).

  3. Al final del archivo, antes de la etiqueta de cierre </Project>, agregue el marcado siguiente que especifica cuándo debe ejecutarse el nuevo destino.

    <PropertyGroup>
        <CopyAllFilesToSingleFolderForPackageDependsOn>
          CustomCollectFiles;
          $(CopyAllFilesToSingleFolderForPackageDependsOn);
        </CopyAllFilesToSingleFolderForPackageDependsOn>
    
        <CopyAllFilesToSingleFolderForMsdeployDependsOn>
          CustomCollectFiles;
          $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
        </CopyAllFilesToSingleFolderForMsdeployDependsOn>
    </PropertyGroup>
    

    Este código hace que el nuevo destino CustomCollectFiles se ejecute siempre que se ejecute el destino que copia los archivos en la carpeta de destino. Hay un destino independiente para la publicación frente a la creación de paquetes de implementación, y el nuevo destino se inserta en ambos destinos en caso de que decida implementar mediante un paquete de implementación en lugar de publicarlo.

    Ahora el archivo .pubxml es similar al del siguiente ejemplo:

    <?xml version="1.0" encoding="utf-8"?>
    <!--
    This file is used by the publish/package process of your Web project. You can customize the behavior of this process
    by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121. 
    -->
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <WebPublishMethod>MSDeploy</WebPublishMethod>
        <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
        <LastUsedPlatform>Any CPU</LastUsedPlatform>
        <SiteUrlToLaunchAfterPublish>http://contosou-staging.azurewebsites.net</SiteUrlToLaunchAfterPublish>
        <ExcludeApp_Data>True</ExcludeApp_Data>
        <MSDeployServiceURL>waws-prod-bay-001.publish.azurewebsites.windows.net:443</MSDeployServiceURL>
        <DeployIisAppPath>contosou-staging</DeployIisAppPath>
        <RemoteSitePhysicalPath />
        <SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
        <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
        <UserName>$contosou-staging</UserName>
        <_SavePWD>True</_SavePWD>
        <PublishDatabaseSettings>
          <Objects xmlns="">
            <ObjectGroup Name="SchoolContext" Order="1" Enabled="True">
              <Destination Path="Data Source=tcp:sk0264hvc9.database.windows.net,1433;Initial Catalog=ContosoUniversity-staging;User ID=CU-staging-admin@sk0264hvc9;Password=" Name="Data Source=tcp:sk0264hvc9.database.windows.net,1433;Initial Catalog=ContosoUniversity-staging;User Id=CU-staging-admin@sk0264hvc9;Password=" />
              <Object Type="DbCodeFirst">
                <Source Path="DBMigration" DbContext="ContosoUniversity.DAL.SchoolContext, ContosoUniversity.DAL" MigrationConfiguration="ContosoUniversity.DAL.Migrations.Configuration, ContosoUniversity.DAL" Origin="Configuration" />
              </Object>
            </ObjectGroup>
            <ObjectGroup Name="DefaultConnection" Order="2" Enabled="False">
              <Destination Path="Data Source=tcp:sk0264hvc9.database.windows.net,1433;Initial Catalog=ContosoUniversity-staging;User ID=CU-staging-admin@sk0264hvc9;Password=" Name="Data Source=tcp:sk0264hvc9.database.windows.net,1433;Initial Catalog=ContosoUniversity-staging;User Id=CU-staging-admin@sk0264hvc9;Password=" />
              <Object Type="DbDacFx">
                <PreSource Path="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-ContosoUniversity.mdf;Initial Catalog=aspnet-ContosoUniversity;Integrated Security=True" includeData="False" />
                <Source Path="$(IntermediateOutputPath)AutoScripts\DefaultConnection_IncrementalSchemaOnly.dacpac" dacpacAction="Deploy" />
              </Object>
              <UpdateFrom Type="Web.Config">
                <Source MatchValue="Data Source=(LocalDb)\v11.0;Integrated Security=SSPI;Initial Catalog=aspnet-ContosoUniversity;AttachDBFilename=|DataDirectory|\aspnet-ContosoUniversity.mdf" MatchAttributes="$(UpdateFromConnectionStringAttributes)" />
              </UpdateFrom>
              <Object Type="DbFullSql" Enabled="False">
                <Source Path="..\aspnet-data-prod.sql" Transacted="False" />
              </Object>
            </ObjectGroup>
          </Objects>
        </PublishDatabaseSettings>
        <EnableMSDeployBackup>False</EnableMSDeployBackup>
      </PropertyGroup>
      <ItemGroup>
        <MSDeployParameterValue Include="$(DeployParameterPrefix)DefaultConnection-Web.config Connection String">
          <ParameterValue>Data Source=tcp:sk0264hvc9.database.windows.net,1433;Initial Catalog=ContosoUniversity-staging;User Id=CU-staging-admin@sk0264hvc9;Password=</ParameterValue>
        </MSDeployParameterValue>
        <MSDeployParameterValue Include="$(DeployParameterPrefix)SchoolContext-Web.config Connection String">
          <ParameterValue>Data Source=tcp:sk0264hvc9.database.windows.net,1433;Initial Catalog=ContosoUniversity-staging;User Id=CU-staging-admin@sk0264hvc9;Password=</ParameterValue>
        </MSDeployParameterValue>
      </ItemGroup>
      <Target Name="CustomCollectFiles">
        <ItemGroup>
          <_CustomFiles Include="..\ExtraFiles\**\*" />
          <FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
            <DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
          </FilesForPackagingFromProject>
        </ItemGroup>
      </Target>
      <PropertyGroup>
        <CopyAllFilesToSingleFolderForPackageDependsOn>
          CustomCollectFiles;
          $(CopyAllFilesToSingleFolderForPackageDependsOn);
        </CopyAllFilesToSingleFolderForPackageDependsOn>
    
        <CopyAllFilesToSingleFolderForMsdeployDependsOn>
          CustomCollectFiles;
          $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
        </CopyAllFilesToSingleFolderForMsdeployDependsOn>
      </PropertyGroup>
    </Project>
    
  4. Guarde y cierre el archivo Staging.pubxml.

Publicación en almacenamiento provisional

Mediante la publicación con un solo clic o la línea de comandos, publique la aplicación usando el perfil de almacenamiento provisional.

Si usa la publicación con un solo clic, puede comprobar en la ventana Vista previa que se copiará robots.txt. De lo contrario, use la herramienta FTP para comprobar que el archivo robots.txt está en la carpeta raíz del sitio web después de la implementación.

Resumen

Esto completa esta serie de tutoriales sobre la implementación de una aplicación web de ASP.NET en un proveedor de hospedaje de terceros. Para obtener más información sobre cualquiera de los temas tratados en estos tutoriales, consulte el mapa de contenido de implementación de ASP.NET.

Información adicional

Si sabe cómo trabajar con archivos de MSBuild, puede automatizar muchas otras tareas de implementación escribiendo código en archivos .pubxml (para tareas específicas del perfil) o el archivo .wpp.targets del proyecto (para tareas que se aplican a todos los perfiles). Para obtener más información sobre los archivos .pubxml y .wpp.targets, consulte Procedimiento: Edición de valores de implementación en archivos de perfil de publicación (.pubxml) y el archivo .wpp.targets en proyectos web de Visual Studio. Para ver una introducción básica al código de MSBuild, consulte Anatomía de un archivo del proyecto en Serie de implementación empresarial: descripción del archivo de proyecto. Para aprender a trabajar con archivos de MSBuild para realizar tareas en sus propios escenarios, consulte este libro: Inside the Microsoft Build Engine: Using MSBuild and Team Foundation Build, de Sayed Ibraham Hashimi y William Bartholomew.

Agradecimientos

Me gustaría agradecer a las siguientes personas que han aportado contribuciones significativas al contenido de esta serie de tutoriales: