WebDeploy Packaging with ASP.NET Core

I’ve seen lots of questions recently regarding if/how deployment of ASP.NET Core applications changed from previous versions of ASP.NET.  The good news is many of the old capabilities exist, although you will likely have to adjust your deployment processes to utilize them.  In this post, I will cover how to deploy an ASP.NET Core application to a WebDeploy package.

ASP.NET Core Web Publishing

Sayed Hashimi wrote a great article explaining how web publishing works in Visual Studio 2015 with ASP.NET Core projects.  The good news is there are now 3 different extension points where we can customize the publish/deployment process.  

image

Although ASP.NET Core projects don’t have the traditional .csproj project file, MSBuild is still used to kickoff the process (with VS or your CI process) and calls the appropriate dotnet commands behind the scenes.  A PowerShell script is added by default with each new publish profile as well as one of the new extension points. 

The ASP.NET Core updates for Visual Studio 2015 also include brand new MSBuild .targets files for deploying ASP.NET Core applications.  Most of the meat is in the Microsoft.DotNet.Publishing.targets file.

image

DeployOnBuild Property

In previous versions of ASP.NET you typically initiated the publish process by adding the /p:DeployOnBuild=true as an MSBuild argument in your build.  Depending on how your publishing your ASP.NET Core project that may have mixed results.  For example, if you create a publish profile for creating a WebDeploy package for a ASP.NET Core project that has dependencies on other .NET Core libraries you can get errors:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Publishing.targets(149,5): error : Can not find runtime target for framework '.NETStandard,Version=v1.6' compatible with one of the target runtimes: 'win7-x64'. Possible causes: [D:\GitHub\AcmeApp.NET\src\AcmeApp.NET.Domain\AcmeApp.
NET.Domain.xproj]
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Publishing.targets(149,5): error : 1. The project has not been restored or restore failed - run `dotnet restore` [D:\GitHub\AcmeApp.NET\src\AcmeApp.NET.Domain\AcmeApp.NET.Domain.xproj]
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Publishing.targets(149,5): error : 2. The project does not list one of 'win7-x64' in the 'runtimes' section. [D:\GitHub\AcmeApp.NET\src\AcmeApp.NET.Domain\AcmeApp.NET.Domain.xproj]
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DotNet\Microsoft.DotNet.Publishing.targets(149,5): error : 3. You may be trying to publish a library, which is not supported. Use `dotnet pack` to distribute libraries. [D:\GitHub\AcmeApp.NET\src\AcmeApp.NET.Domain\AcmeApp.NET.Domain.xproj]

In this case, the dotnet publish command is attempting to publish the .NET Core library but libraries are intended to be packaged not published according to the .NET Core team.

If you don’t have any .NET Core library project references, this would build and publish without error.  So it depends on your project and how your publishing.

WebDeploy Packaging for ASP.NET Core

We can still create a WebDeploy package for our project  with a .NET Core library reference by running the PackagePublish target from the commandline instead of setting the DeployOnBuild property to true. 

D:\GitHub\AcmeApp.NET\src\AcmeApp.NET.Web>"c:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild" /t:PackagePublish /p:PublishProfile=Package

This will skip trying to publish the library project and instead only publish the web project thus avoiding the above error. 

The Publish Profile can be created using the VS Web Publish dialog as described in my previous post Deploy ASP.nET Core 1.0 (RTM) to Azure App Service.  The following is an example of the .pubxml generated for a Package publish:

<?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 http://go.microsoft.com/fwlink/?LinkID=208121. 
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>Package</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <PublishFramework>netcoreapp1.0</PublishFramework>
    <UsePowerShell>True</UsePowerShell>
    <DesktopBuildPackageLocation>bin\debug\package.zip</DesktopBuildPackageLocation>
    <PackageAsSingleFile>true</PackageAsSingleFile>
    <DeployIisAppPath />
  </PropertyGroup>
</Project>

Notice above the DesktopBuildPackageLocation node which specifies where to place the package file.  You can manually edit this to be more flexible by referencing other MSBuild properties.  For example,

    <DesktopBuildPackageLocation>bin\$(Configuration)\$(MSBuildProjectName).zip</DesktopBuildPackageLocation>

This will be overwritten however if you open the publish profile via the VS publish dialog. This isn’t typically a problem for us because we rarely use the VS publish dialog once we have a good CD pipeline.

Building via VSTS/TFS

We can also create the package via our CI process by adding the same MSBuild arguments to our Visual Studio Build task:

image

This task will output a WebDeploy package so we can deploy the same exact package to multiple environments from our Release Definition.

Feedback

Please let me know if this post was helpful or if you have further questions that I can help resolve.  You can leave a comment below or start a conversation on Twitter or Reddit.

11 thoughts on “WebDeploy Packaging with ASP.NET Core”

  1. I am not able to get the VSTS/TFS step with the xproj file to create a zip file in this manner. Is there some special way you have to call the Publish Profile?

  2. The name of my publish profile is QA-Package, but yes, I have Package in that file and /t:PackagePublish /p:PublishProfile=QA-Publish on that build task.

  3. I am not at liberty to provide the code, as it belongs to a client, but I can see both from the build definition and from doing an MSBuild at the command line that the output is going to a Temp directory in the users’ folder. But what is there is what I would expect from a “dotnet publish” and the zip file is not there.

    I also notice in your VSTS/TFS example that it is label MSDeploy…is this really MSBuild or it is MSDeploy>?

    Here is the output from the command line:

    F:\dev\PracticeArea\SupportServiceCore1.0.0\src\SupportService>MSBuild /t:Packag
    ePublish /p:PublishProfile=QA-Package
    Microsoft (R) Build Engine version 14.0.25420.1
    Copyright (C) Microsoft Corporation. All rights reserved.

    Build started 11/2/2016 11:52:40 PM.
    Project “F:\dev\PracticeArea\SupportServiceCore1.0.0\src\SupportService\Support
    Service.xproj” on node 1 (PackagePublish target(s)).
    GatherAllFilesToPublish:
    rmdir /S /Q “C:\Users\mayeager.adm\AppData\Local\Temp\2\PublishTemp\SupportSe
    rvice83\”
    Environment variables:
    Path=F:\dev\PracticeArea\SupportServiceCore1.0.0\src\SupportService\node_modu
    les\.bin;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Web\External;C:\
    Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions
    \Microsoft\TestWindow;C:\Program Files (x86)\MSBuild\14.0\bin;C:\Program File
    s (x86)\Microsoft Visual Studio 14.0\Common7\IDE\;C:\Program Files (x86)\Micr
    osoft Visual Studio 14.0\VC\BIN;C:\Program Files (x86)\Microsoft Visual Studi
    o 14.0\Common7\Tools;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Program
    Files (x86)\Microsoft Visual Studio 14.0\VC\VCPackages;C:\Program Files (x86
    )\Microsoft Visual Studio 14.0\Team Tools\Performance Tools;C:\Program Files
    (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\;C:\Windows\system3
    2;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v
    1.0\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\M
    icrosoft SQL Server\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Cli
    ent SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\130\
    Tools\Binn\;C:\Program Files\Microsoft SQL Server\130\DTS\Binn\;C:\Program Fi
    les (x86)\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Fil
    es (x86)\Microsoft SQL Server\130\DTS\Binn\;C:\Program Files (x86)\Microsoft
    SQL Server\130\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft
    SQL Server\110\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\
    Binn\;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files\nod
    ejs\;C:\Program Files\Microsoft DNX\Dnvm\;C:\Program Files\dotnet\;C:\Program
    Files\Git\cmd;C:\Users\mayeager.adm\.dnx\runtimes\dnx-clr-win-x86.1.0.0-rc1-
    update2\bin;C:\Users\mayeager.adm\.dnx\bin;C:\Users\mayeager.adm\AppData\Roam
    ing\npm;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Web\External\git
    C:\Program Files\dotnet\dotnet.exe publish “F:\dev\PracticeArea\SupportServic
    eCore1.0.0\src\SupportService” –framework netcoreapp1.0 –output “C:\Users\m
    ayeager.adm\AppData\Local\Temp\2\PublishTemp\SupportService83” –configuratio
    n Release –no-build
    Publishing SupportService for .NETCoreApp,Version=v1.0
    Configuring the following project for use with IIS: ‘C:\Users\mayeager.adm\Ap
    pData\Local\Temp\2\PublishTemp\SupportService83’
    Updating web.config at ‘C:\Users\mayeager.adm\AppData\Local\Temp\2\PublishTem
    p\SupportService83\web.config’
    Configuring project completed successfully
    publish: Published to C:\Users\mayeager.adm\AppData\Local\Temp\2\PublishTemp\
    SupportService83
    Published 1/1 projects successfully
    Done Building Project “F:\dev\PracticeArea\SupportServiceCore1.0.0\src\SupportS
    ervice\SupportService.xproj” (PackagePublish target(s)).

    Build succeeded.
    0 Warning(s)
    0 Error(s)

    Time Elapsed 00:00:26.44

  4. What if I actually want to deploy to the server for real? Do I just set my webdeploy parameters in the publish dialog. Do I need any different arguments to get this to work?

    1. You can change the MSBuild args to actually deploy during the build but I consider that a bad practice. You should only build once and then deploy the resulting package many times. I would suggest using a separate task to deploy the WebDeploy package.

  5. Does anyone know how to include a custom xml file? I need an custom xml file in my Core ASP project, but when creating the deploy package none is copied inside the zip file. I have searched the web but cannot find a solution.

  6. Pingback: WebDeploy Packaging with ASP.NET Core 2.0 (includes Function Apps) – DOTNET CATCH

Leave a Reply