| File: Tasks\TransformWebConfig.cs | Web Access |
| Project: src\sdk\src\WebSdk\Publish\Tasks\Microsoft.NET.Sdk.Publish.Tasks.csproj (Microsoft.NET.Sdk.Publish.Tasks) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Xml; using Microsoft.Build.Framework; namespace Microsoft.NET.Sdk.Publish.Tasks { public class TransformWebConfig : Task { /// <summary> /// The full path to the assembly or executable to be compiled, including file extension /// </summary> /// <returns></returns> [Required] public string? TargetPath { get; set; } /// <summary> /// Destination folder of the publish /// </summary> /// <returns></returns> [Required] public string? PublishDir { get; set; } [Required] public bool UseAppHost { get; set; } /// <summary> /// [optional] Transform is targeted for Azure /// </summary> /// <returns></returns> public bool IsAzure { get; set; } /// <summary> /// ProjectGuid that uniquely identifies the project. Used for Telemetry /// </summary> public string? ProjectGuid { get; set; } /// <summary> /// Flag that determines whether the publish telemetry needs to be disabled. /// </summary> public bool IgnoreProjectGuid { get; set; } /// <summary> /// Absolute path to the project file. /// </summary> public string? ProjectFullPath { get; set; } /// <summary> /// Absolute path to the Solution file. /// </summary> public string? SolutionPath { get; set; } /// <summary> /// Native executable extension /// </summary> public string? ExecutableExtension { get; set; } /// <summary> /// AspNetCoreHostingModel defines whether the hosting will be InProcess or OutOfProcess. /// </summary> /// <returns></returns> public string? AspNetCoreHostingModel { get; set; } /// <summary> /// AspNetCoreModule defines the module name /// </summary> /// <returns></returns> public string? AspNetCoreModuleName { get; set; } public string? EnvironmentName { get; set; } public override bool Execute() { Log.LogMessage(MessageImportance.Low, $"Configuring the following project for use with IIS: '{PublishDir}'"); XDocument? webConfigXml = null; // Initialize the publish web.config file with project web.config content if present. Else, clean the existing web.config in the // publish folder to make sure we have a consistent web.config update experience. string defaultWebConfigPath = "web.config"; string? projectWebConfigPath = null; string publishWebConfigPath = string.Empty; if (PublishDir is not null) { publishWebConfigPath = Path.Combine(PublishDir, defaultWebConfigPath); } if (ProjectFullPath is not null && ProjectFullPath.Length != 0 && PublishDir is not null) { //Ensure that we load the actual web.config name (case-sensitive on Unix-like systems) projectWebConfigPath = GetWebConfigFileOrDefault(ProjectFullPath, defaultWebConfigPath); publishWebConfigPath = Path.Combine(PublishDir, Path.GetFileName(projectWebConfigPath)); } publishWebConfigPath = Path.GetFullPath(publishWebConfigPath); if (File.Exists(publishWebConfigPath)) { if (File.Exists(projectWebConfigPath)) { File.Copy(projectWebConfigPath, publishWebConfigPath, true); } else { File.WriteAllText(publishWebConfigPath, WebConfigTemplate.Template); } Log.LogMessage($"Updating web.config at '{publishWebConfigPath}'"); try { webConfigXml = XDocument.Load(publishWebConfigPath); } catch (XmlException e) { Log.LogWarning($"Cannot parse web.config as XML. A new web.config will be generated. Error Details : {e.Message}"); } } else { Log.LogMessage($"No web.config found. Creating '{publishWebConfigPath}'"); } if (IsAzure) { Log.LogMessage("Configuring web.config for deployment to Azure"); } string? outputFile = Path.GetFileName(TargetPath) ?? string.Empty; XDocument? transformedConfig = WebConfigTransform.Transform( webConfigXml, outputFile, IsAzure, UseAppHost, ExecutableExtension, AspNetCoreModuleName, AspNetCoreHostingModel, EnvironmentName, ProjectFullPath); // Telemetry transformedConfig = WebConfigTelemetry.AddTelemetry(transformedConfig, ProjectGuid, IgnoreProjectGuid, SolutionPath, ProjectFullPath); using (FileStream f = new(publishWebConfigPath, FileMode.Create)) { transformedConfig?.Save(f); } Log.LogMessage(MessageImportance.Low, "Configuring project completed successfully"); return true; } /// <summary> /// Searches for an existing (case-insensitive) `Web.config` file. Otherwise defaults to defaultWebConfigName /// </summary> /// <param name="projectPath">Full path to project file</param> /// <param name="defaultWebConfigName">Web Config file name to search for i.e. `web.config`</param> /// <returns></returns> public string GetWebConfigFileOrDefault(string projectPath, string defaultWebConfigName) { var projectDirectory = Path.GetDirectoryName(projectPath); if (projectDirectory is null) { return string.Empty; } var currentWebConfigFileName = Directory.EnumerateFiles(projectDirectory) .FirstOrDefault(file => string.Equals(Path.GetFileName(file), defaultWebConfigName, StringComparison.OrdinalIgnoreCase)); var webConfigFileName = currentWebConfigFileName == null ? defaultWebConfigName : Path.GetFileName(currentWebConfigFileName); var projectWebConfigPath = Path.Combine(projectDirectory, webConfigFileName); return projectWebConfigPath; } } }