【c#】 Web Deploy一键发布,IIS部署全流程

项目:ASP.NET Core 8.0 Web API

服务器:阿里云 Windows Server + IIS

部署方式:VS Web Deploy 一键发布


一、前置准备

1.1 本地环境

说明
项目框架 .NET 8.0
开发工具 Visual Studio
发布方式 Web Deploy(直接推送到远程 IIS)

1.2 服务器环境

说明
操作系统 Windows Server(阿里云)
公网 IP XXXX
Web 服务器 IIS(已安装)

1.3 代码调整

Program.cs 中 Swagger 原本只在开发环境启用:

csharp 复制代码
// 修改前
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

// 修改后(去掉环境判断,生产也可见)
app.UseSwagger();
app.UseSwaggerUI();

二、服务器端安装与配置

2.1 安装 .NET 8 Hosting Bundle

下载地址:https://dotnet.microsoft.com/zh-cn/download/dotnet/8.0

注意 :Hosting Bundle 不是独立板块,它在 ASP.NET Core 运行时 那一行的链接里,找 "Hosting Bundle" 这个小链接。

安装时选最新版 8.0.29,安装完成后重启 IIS:

powershell 复制代码
iisreset

2.2 安装 IIS 管理服务(Management Service)

Web Deploy 需要管理服务来接收远程发布请求。

powershell 复制代码
Install-WindowsFeature Web-Mgmt-Service

2.3 安装 Web Deploy

下载:https://www.iis.net/downloads/microsoft/web-deploy

Web Deploy 4.0 ,安装时选择 更改(Change) ,务必勾选所有子组件(尤其是 IIS Deployment Handler),否则 msdeploy 处理器不会注册到 IIS。

2.4 启用远程连接

  1. 打开 IIS 管理器
  2. 左侧选中服务器节点(最顶层)
  3. 双击 管理服务
  4. 先点右侧 停止
  5. 勾选 启用远程连接
  6. 端口保持默认 8172
  7. 点右侧 应用启动

2.5 放行端口

Windows 防火墙

添加入站规则,放行 TCP 端口 81728080(站点端口)。

阿里云安全组

在阿里云控制台 → 安全组 → 入方向规则,添加:

端口 协议 用途
8080 TCP 站点访问
8172 TCP Web Deploy 远程发布

2.6 创建 IIS 站点

设置项
站点名称 JpaasPrinter
物理路径 C:\inetpub\wwwroot\JpaasPrinter
绑定端口 8080
应用程序池 .NET CLR 版本 无托管代码
托管管道模式 集成

2.7 设置文件夹权限

站点物理路径(如 C:\inetpub\wwwroot\JpaasPrinter)需要让 IIS 应用池账户读取。

右键文件夹 → 属性 → 安全 → 编辑 → 添加:

复制代码
IIS AppPool\JpaasPrinter

权限勾选:读取和执行列出文件夹内容读取


三、VS 发布配置

3.1 配置发布配置文件

右键项目 → 发布Web 服务器 (IIS)Web 部署

字段 填写内容
服务器 XXX
站点名称 JpaasPrinter(必须和 IIS 里完全一致)
目标 URL http://XXX:8080
用户名 Administrator
密码 服务器 Administrator 密码

3.2 允许不受信任的证书

Windows Server 的 IIS 管理服务使用自签名证书,VS 默认不信任。两种修复方式:

方式 A (推荐):编辑 Properties\PublishProfiles\IISProfile.pubxml,添加:

xml 复制代码
<AllowUntrustedCertificate>true</AllowUntrustedCertificate>

方式 B :在 VS 发布页面 → 更多连接选项 → 勾选 允许不受信任的证书


四、遇到的问题及解决

问题 1:找不到 Hosting Bundle 下载

现象:.NET 8.0 下载页面没有独立叫 "Hosting Bundle" 的板块。

原因 :Hosting Bundle 的下载链接藏在 ASP.NET Core 运行时 那一行的小字链接里。

解决 :展开某个版本号,在"ASP.NET Core 运行时"行中找到 "Hosting Bundle" 链接,或直接访问:

https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/runtime-aspnetcore-8.0.29-windows-hosting-bundle-installer


问题 2:IIS 里看不到管理服务

现象:装了 Web Deploy 但 IIS 管理器里没有出现"管理服务"功能。

原因:管理服务(Management Service)是 IIS 的一个独立功能,不随 Web Deploy 安装。

解决

powershell 复制代码
Install-WindowsFeature Web-Mgmt-Service

问题 3:VS 验证连接报 404

现象

复制代码
Web 部署任务失败。远程服务器返回了错误 (404) 未找到。

原因(两个可能):

  1. 管理服务"启用远程连接"没打勾
  2. Web Deploy 的 msdeploy.axd 处理器没注册到 IIS

排查

powershell 复制代码
# 检查 WMSVC 服务和 IIS 管理服务状态
Get-Service WMSVC
Get-WindowsFeature Web-Mgmt-Service
Test-NetConnection 8.135.xx.xx -Port 8172

# 检查 msdeploy 处理器
Get-WebHandler | Where-Object { $_.Name -like "*msdeploy*" }

解决

  • 如端口不通 → 检查防火墙和安全组
  • 如管理服务没启用 → IIS 管理器里勾选"启用远程连接"
  • 如处理器丢失 → 修复 Web Deploy 安装,确保勾选 IIS Deployment Handler

问题 4:证书验证失败

现象

复制代码
ERROR_CERTIFICATE_VALIDATION_FAILED

原因:IIS 管理服务使用自签名证书,VS 不信任。

解决:在发布配置文件中添加:

xml 复制代码
<AllowUntrustedCertificate>true</AllowUntrustedCertificate>

五、发布时的行为说明

文件替换机制

  • ASP.NET Core 使用影子复制 :IIS 启动时会从 publish 目录复制文件到临时目录再执行,原始文件不被锁定。
  • 发布时 Web Deploy 可以直接覆盖原始文件,不会被"文件使用中"拦住。
  • 覆盖完成后,ASP.NET Core Module 检测到文件变化,自动回收旧进程,用新文件重新启动。

站点是否停机

发布过程中站点不会主动停止。文件替换后新进程自动启动,切换期间可能 1-3 秒请求失败(502/503),流量小的项目无需在意。


六、快速参考

常用命令

powershell 复制代码
# 重启 IIS
iisreset

# 检查管理服务状态
Get-Service WMSVC

# 检查 IIS 站点列表
Get-Website | Select-Object Name, PhysicalPath, State

# 检查端口连通性
Test-NetConnection 8.135.xx.xx -Port 8172
Test-NetConnection 8.135.xx.xx -Port 8080

# 检查 Web Deploy 处理器
Get-WebHandler | Where-Object { $_.Name -like "*msdeploy*" }

端口清单

端口 协议 用途 需放行位置
8080 TCP 网站访问 阿里云安全组 + Windows 防火墙
8172 TCP Web Deploy 发布 阿里云安全组 + Windows 防火墙

相关推荐
宁&沉沦1 小时前
Chrome 扩展 Manifest 字段版本支持一览(全量)
前端·后端·编辑器
乖孩子2 小时前
Service Worker + IndexedDB 实践
前端
Brilliantwxx2 小时前
【Linux】 软件包管理器(yum)+ Vim使用
linux·运维·服务器·开发语言·编辑器·vim
雪的季节2 小时前
Python 线程同步与异步编程 全解析
java·开发语言
浮生望2 小时前
BFF架构实战:用Express+SSE为Vue3搭建安全的流式对话中间层
前端
520拼好饭被践踏2 小时前
JAVA+Agent学习day22
java·开发语言·后端·学习
先吃饱再说2 小时前
React 组件通信:从 Props 单向传递到自定义事件
前端·react.js·前端框架
笨蛋不要掉眼泪2 小时前
Java虚拟机:堆的参数配置
java·开发语言·jvm
swipe2 小时前
05|(前端转后全栈)不手写一堆 SQL,后端怎么操作数据库?MyBatis-Plus 入门
前端·后端·全栈