In ASP.NET when you publish a Visual Studio web project MSBuild is used to drive the entire process. The project file (.csproj or .vbproj) is used to gather
the files that need to be published as well as perform any updates during publish (for example updating web.config). The project file contains the full list
of files as well as their type. That information is used to determine the files to publish. The logic was implemented in an MSBuild .targets file. During the
publish process MSBuild will call Web Deploy (msdeploy.exe) to transfer the files to the final location. To customize the publish process you would need to
update the publish profile, or project file, with custom MSBuild elements.
In ASP.NET Core the publish process has been simplified, we no longer store a reference to files that the project contains. All files are included in the
project by default (files can be excluded from the project or from publish by updating *project.json*). When you publish an ASP.NET Core project from
1. A publish profile is created at `Properties\PublishProfiles\profilename.pubxml`. The publish profile is an MSBuild file.
2. A PowerShell script is created at `Properties\PublishProfiles\profilename.ps1`.
3.`dotnet publish` is called to gather the files to publish to a temporary folder.
4. A PowerShell script is called passing in the properties from the publish profile and the location where `dotnet publish` has placed the files to publish.
To create a publish profile in Visual Studio, right click on the project in Solution Explorer and then select Publish.
The following image shows a visualization of this process.
When you start a publish operation, the publish dialog is closed and then MSBuild is called to start the process. Visual Studio calls MSBuild to do this so that
you can have parity with publishing when using Visual Studio or the command line. The MSBuild layer is pretty thin, for the most part it just calls `dotnet publish`.
The `dotnet publish` command will inspect project.json and the project folder to determine the files which need to be published. It will place the files needed to
run the application in a single folder ready to be transferred to the final destination.
After `dotnet publish` has completed, the PowerShell script for the publish profile is called. Now that we have briefly discussed how publishing works at a high
level let’s take a look at the structure of the PowerShell script created for publishing.
The parameters of the script define the contract between Visual Studio and the PowerShell script. You should not change the declared parameters because Visual Studio
depends on those. You can add additional parameters, but they must be added at the end.
The publish module version, denoted by `$publishModuleVersion`, defines the version of the web publish module that will be used. Valid version numbers can be found
from published versions of the [publish-module NuGet package](https://www.nuget.org/packages/publish-module) on nuget.org. Once you create a publish profile the
script definition is locked to a particular version of the publish-module package. If you need to update the version of the script you can delete the .ps1 file
and then publish again in Visual Studio to get a new script created.
The call to Publish-AspNet moves the files from your local machine to the final destination. Publish-AspNet will be passed all the properties defined in the .pubxml
file, even custom properties. For Web Deploy publish, msdeploy.exe will be called to publish the files to the destination. Publish-AspNet is passed the same
parameters as the original script. You can get more info on the parameters for Publish-AspNet use Get-Help Publish-AspNet. If you get an error that the publish-module
from a machine which has Visual Studio installed. Now let’s move on to discuss how to customize the publish process.
How to customize publishing In the previous section we saw the visualization of the publish process. The image is shown again to make this easier to follow.
Most developers will not need to customize this extension point. Visual Studio starts the publish process by calling an MSBuild target. This target will take care of
initializing the environment and calling `dotnet publish` to layout the files. If you need to customize that call in a way that is not enabled by the publish dialog
then you can use MSBuild elements in either the project file (.xproj file) or the publish profile (.pubxml file). We won’t get into details of how to do that here as
it’s an advanced scenario that few will need to extend.
As stated previously `dotnet publish` is a command-line utility that can be used to help publish your ASP.NET Core application. This is a cross platform command-line
utility (that is, you can use it on Windows, Mac or Linux) and does not require Visual Studio. If you are working on a team in which some developers are not using
Visual Studio, then you may want to script building and publishing. When `dotnet publish` is executed it can be configured to execute custom commands before or after
execution. The commands will be listed in project.json in the scripts section.
The supported scripts for publish are prepublish and postpublish. The ASP.NET Core Web Application template uses the prepublish step by default. The relevant snippet
When Visual Studio is used the prepublish and postpublish steps are executed as a part of the call to `dotnet publish`. The postpublish script from *project.json* is
executed before the files are published to the remote destination because that takes place immediately after `dotnet publish` completes. In the next step we cover
customizing the PowerShell script to control what happens to the files after they reach the target destination.
3. Customize the publish profile PowerShell Script
After creating a publish profile in Visual Studio the PowerShell script `Properties\PublishProfiles\ProfileName.ps1` is created. The script does the following:
1. Runs `dotnet publish`, which will package the web project into a temporary folder to prepare it for the next phase of publishing.
2. The profile PowerShell script is directly invoked. The publish properties and the path to the temporary folder are passed in as parameters. Note, the temporary folder
*`$publishProperties` is a PowerShell hashtable which contains all the properties declared in the profile .pubxml file. It also includes values for file text replacements
or files to exclude. For more info on the values for `$publishProperties` use `Get-Help publish-aspnet –Examples`.
To customize this process, you can edit the PowerShell script directly. To perform an action before publish starts, add the action before the call to `Publish-AspNet`.
To have an action performed after publish, add the appropriate calls after Publish-AspNet. When Publish-AspNet is called the contents of the $packOutput directory are
published to the destination. For example, if you need add a file to the publish process, just copy it to the correct location in `$packOutput` before `Publish-AspNet`
is called. The snippet below shows how to do that.
In this snippet external images are copied from `c:\resources\external-images to $packOutput\wwwroot\external-images`. Before starting the copy operation the script ensures
that the destination folder exists. Since the copy operation takes place before the call to `Publish-AspNet` the new files will be included in the published content.
To perform actions after the files have reached the destination then you can place those commands after the call to `Publish-AspNet`.
You are free to customize, or even completely replace, the Publish-AspNet script provided. As previously mentioned, you will need to preserve the parameter declaration,