Azure Pipeline如何按常规目录结构发布ASP.NET MVC应用
ASP.NET MVC项目Azure DevOps构建产物路径异常问题处理
问题背景
我有一个包含多个项目的解决方案,目标是获取可直接复制到服务器部署的ASP.NET MVC项目UserUi.csproj作为构建产物(该项目引用了解决方案内的其他类库)。使用以下YAML配置运行Azure DevOps流水线后:
trigger: - master pool: vmImage: "windows-latest" variables: solution: "**/*.sln" buildPlatform: "Any CPU" buildConfiguration: "Release" steps: - task: NuGetToolInstaller@1 - task: NuGetCommand@2 inputs: restoreSolution: "$(solution)" - task: VSBuild@1 inputs: solution: "$(solution)" msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=FileSystem /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)\UserUi"' platform: "$(buildPlatform)" configuration: "$(buildConfiguration)" - task: VSTest@2 inputs: platform: "$(buildPlatform)" configuration: "$(buildConfiguration)" - task: PublishBuildArtifacts@1 inputs: PathtoPublish: '$(Build.ArtifactStagingDirectory)\UserUi' ArtifactName: 'drop' publishLocation: 'Container'
出现以下问题:
- 生成了多余的deploy文件
- 得到的
UserUi.deploy.zip解压后,文件嵌套在UserUi.zip\Content\D_C\a\1\s\4. SampleLayer\UserUi\obj\Release\Package\PackageTmp路径下,无法直接用于服务器部署
原因分析
- 编译范围错误:VSBuild任务指定编译整个解决方案(
$(solution)),加上DeployOnBuild=true参数,会导致所有项目都执行部署打包操作,产生多余的deploy文件。 - 打包参数冲突:
PackageAsSingleFile=true会触发MSBuild的传统打包逻辑,生成包含完整本地构建路径的zip包,而非直接输出部署所需的文件;PackageLocation参数仅指定zip包的生成位置,不会调整包内的文件结构。
解决方案
方案1:直接输出可部署的文件夹(推荐)
修改VSBuild任务,仅编译目标项目UserUi.csproj,调整MSBuild参数去掉PackageAsSingleFile=true,使用publishUrl指定输出目录,让部署文件直接输出到指定路径:
trigger: - master pool: vmImage: "windows-latest" variables: solution: "**/*.sln" buildPlatform: "Any CPU" buildConfiguration: "Release" steps: - task: NuGetToolInstaller@1 - task: NuGetCommand@2 inputs: restoreSolution: "$(solution)" - task: VSBuild@1 inputs: solution: '**/UserUi.csproj' # 仅编译目标MVC项目 msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=FileSystem /p:SkipInvalidConfigurations=true /p:publishUrl="$(build.artifactStagingDirectory)\UserUi"' platform: "$(buildPlatform)" configuration: "$(buildConfiguration)" # 若不需要测试可移除该任务,或调整为仅测试目标项目相关用例 - task: VSTest@2 inputs: platform: "$(buildPlatform)" configuration: "$(buildConfiguration)" - task: PublishBuildArtifacts@1 inputs: PathtoPublish: '$(Build.ArtifactStagingDirectory)\UserUi' ArtifactName: 'drop' publishLocation: 'Container'
调整后,$(build.artifactStagingDirectory)\UserUi目录下会直接存放所有部署所需的文件,可直接复制到服务器指定目录使用。
方案2:输出仅包含部署文件的压缩包
如果需要输出单个zip包,在方案1的基础上添加ArchiveFiles任务,将部署文件夹打包为无冗余路径的zip:
trigger: - master pool: vmImage: "windows-latest" variables: solution: "**/*.sln" buildPlatform: "Any CPU" buildConfiguration: "Release" steps: - task: NuGetToolInstaller@1 - task: NuGetCommand@2 inputs: restoreSolution: "$(solution)" - task: VSBuild@1 inputs: solution: '**/UserUi.csproj' msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=FileSystem /p:SkipInvalidConfigurations=true /p:publishUrl="$(build.artifactStagingDirectory)\UserUi"' platform: "$(buildPlatform)" configuration: "$(buildConfiguration)" # 添加打包任务,直接打包部署文件 - task: ArchiveFiles@2 inputs: rootFolderOrFile: '$(build.artifactStagingDirectory)\UserUi' includeRootFolder: false # 不包含外层UserUi文件夹,包内直接是部署文件 archiveType: 'zip' archiveFile: '$(build.artifactStagingDirectory)\UserUi.zip' replaceExistingArchive: true - task: VSTest@2 inputs: platform: "$(buildPlatform)" configuration: "$(buildConfiguration)" - task: PublishBuildArtifacts@1 inputs: PathtoPublish: '$(build.artifactStagingDirectory)\UserUi.zip' ArtifactName: 'drop' publishLocation: 'Container'
此方案生成的UserUi.zip解压后直接是部署所需的所有文件,无冗余路径。
内容的提问来源于stack exchange,提问作者guidempty
相关产品推荐
相关产品推荐

