MSBuild.SDK.SystemWeb icon indicating copy to clipboard operation
MSBuild.SDK.SystemWeb copied to clipboard

Support Publish to IIS from withing Visual Studio using the GUI

Open Kation opened this issue 2 years ago • 16 comments

<Project>
  <Import Sdk="Microsoft.NET.Sdk.Publish" Project="Sdk.props" />

  <ItemGroup>
    <ProjectCapability Include="DotNetCoreWeb" />
    <ProjectCapability Include="Web" />
  </ItemGroup>
  <Import Sdk="Microsoft.NET.Sdk.Publish" Project="Sdk.targets" />
</Project>

Add this to enable publish to IIS feature

Kation avatar Sep 02 '21 07:09 Kation

@Kation Publish already works from the command line or build server. Is this to enable the publish command in visual studio? I was aware of the Microsoft.NET.Sdk.Publish SDK type and it appears to include some of the logic and DLLs that are installed by visual studio and are currently pulled in by

<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" />

I feel that adding the DotNetCoreWeb project capability is going to cause the razor editor and other ASP.NET Core features to enable and break working with ASP.NET 4 technologies.

Your example does not include the MSBuild.SDK.SystemWeb so will miss out a lot of the other features and requirements for ASPNET 4.

Have you tried the following?

<Project>
  <Import Sdk="MSBuild.SDK.SystemWeb/4.0.33" Project="Sdk.props" />
  <Import Sdk="Microsoft.NET.Sdk.Publish" Project="Sdk.props" />

  <ItemGroup>
    <ProjectCapability Include="DotNetCoreWeb" />
    <ProjectCapability Include="Web" />
  </ItemGroup>
  <Import Sdk="MSBuild.SDK.SystemWeb/4.0.33" Project="Sdk.targets" />
  <Import Sdk="Microsoft.NET.Sdk.Publish" Project="Sdk.targets" />
</Project>

This will add the MSBuild.SDK.SystemWeb but 'overwrite' the publish targets from Microsoft.NET.Sdk.Publish. If you build an example repository/example which works fully and doesn't break any ASPNET 4 features, we can look at whether this could be added.

CZEMacLeod avatar Sep 02 '21 22:09 CZEMacLeod

@CZEMacLeod Yes. This allow us publish to IIS in Visual Studio. Of course I use MSBuild.SDK.SystemWeb at the top of Project. I have been tested with asp.net mvc but not webform. I found that IIS publish target appear if add project capability only.

Kation avatar Sep 03 '21 02:09 Kation

@CZEMacLeod and @Kation Thank you for the workaround. With the lines above I get the additional publish targets (e.g. IIS) back. But I currently have the issue that if I publish to a folder no files are published. Even if I do a publish from your example projects https://github.com/CZEMacLeod/MSBuild.SDK.SystemWeb/tree/main/samples nothing is published to the publishing folder. If I build from command line with arguments (DeployOnBuild, WebPublishMethod, PackageLocation) publishing is working.

christianbumann avatar Oct 31 '22 13:10 christianbumann

@christianbumann This was never added to the main SDK as it didn't feel like it worked as intended and caused side effects. The fact that it works from the command line means it is easy to integrate this with any CI/CD system, and other than for small/test projects, which wouldn't really benefit from this SDK, it seems like an unlikely use case to be publishing from VS directly. I use the publish mechanism (without any additional settings beyond the SDK), from Azure DevOps for most of my main (ASP.NET4) projects now and it works very well. I'm sure it would also work from GitHub actions too. You could easily set it to publish to a folder and then pick up the folder as artifacts for output, if you want to do it that way. I use MSDeploy and then a release job to actually push the site to our servers.

CZEMacLeod avatar Oct 31 '22 17:10 CZEMacLeod

@CZEMacLeod Thank you for your quick answer. Publishing local from Visual Studio would get a faster feedback how the final package content looks like. Deploying from the pipeline is in plan as the build artefact (deployment package) itself already exists.... Our developers can take the build artefact and extract it if required - or build the solution locally through our Cake-scripts and then the package is also available local.... So we don't really need the local publishing in Visual Studio - I just wanted to ask if there is a quick and easy solution to get this working. But anyway, your answer was helpful for me - and your SDK is great. Have a nice time, Christian

christianbumann avatar Nov 01 '22 08:11 christianbumann

@christianbumann Ah I see. The only thing I can suggest here is to create a batch file in the solution directory and add it to the solution. That way you can execute the batch file from within VS and do the publish command and then investigate the output files etc.

CZEMacLeod avatar Nov 01 '22 20:11 CZEMacLeod

@christianbumann Maybe try one of the following

  • Set <MvcBuildViews>false</MvcBuildViews> in your project and see if the folder now contains what you expect
  • Set the Publish location to a path outside the project directory and see if the folder now contains what you expect

@CZEMacLeod I think there might be a conflict between the "order of operations" in terms of how Visual Studio runs the publish vs running a build. It was something I was investigating but never finished looking into.

I was trying to document the differences between (and the interactions around) the "MvcBuildViews" and the "PreCompileBeforePublish" and how this changed order a little bit when in a ".net core build" as opposed to the original "build", and this as far as I made it when I stopped.

MvcBuildViews target

  • Introduced in VS2010 (slightly altered in VS2012)
  • Enabled to run when Condition="'$(MvcBuildViews)'=='true'"
  • Timed to run with AfterTargets="AfterBuild" note that the meaning of AfterBuild has changed somewhat between older builds and ".net core build" (which now has an "inner" and an "outer" build)
  • Executes task that calls the AspNetCompiler on the current folder structure (and outputs it's content to an ASPNET temp folder... AspNetCompiler was really geared to run against inplace web applications)
  • In VS2013 (I think update 3) a new target <Target Name="CleanupForBuildMvcViews" Condition=" '$(_EnableCleanOnBuildForMvcViews)'=='true' and '$(MVCBuildViews)'=='true' " BeforeTargets="MvcBuildViews"> target was added to the "Microsoft.Web.Publishing.targets"
    • Runs before MvcBuildViews target
    • deletes the contents of several project sub folders, including any folder named "package"... even if that folder is under the "/obj" path, which the default package location usually is.

PreCompileBeforePublish

  • Been available since at least VS2012 (not sure how far back it goes)
  • A property that governs if the "publish" process should run compile aspnet and razorMvc content before packaging
  • Triggers an advanced call to the AspNetCompiler (logic is inside Microsoft.Web.Publishing.AspNetCompileMerge.targets") placing the output of the precompiled files and dlls inside the specified output/packagelocation

I think the conflict comes into play because of when CleanupForBuildMvcViews deletes files and when the "Publish" creates the files (or potentially goes looking for the files to bundle them up)

The oldest VS I currently have installed is 2017, so I can't tell for sure, but by VS 2017 it seems like web project templates

  • moved away from the <MvcBuildViews>true</MvcBuildViews> having the build process call AspNetCompile but rather defaulting to <MvcBuildViews>false</MvcBuildViews>
  • towards having allowing the publish configuration to set <PreCompileBeforePublish>true</PreCompileBeforePublish> letting the publish step call AspNetCompile

leusbj avatar Nov 02 '22 15:11 leusbj

@leusbj Thank you for your suggestions. I tried it but without success. I also combined <MvcBuildViews>false</MvcBuildViews> with <PreCompileBeforePublish>true</PreCompileBeforePublish> and I tried each possible true-false combination without success. Don't investigate extra time for this, as we have a workaround with a *.cmd file building the project with the required arguments, or using the artefact from the build server...

christianbumann avatar Nov 03 '22 07:11 christianbumann