使用 Visual Studio 2022 中的 .http 文件
Visual Studio 2022 .http
文件编辑器提供了一种便捷的方式来测试 ASP.NET Core项目,尤其是 API 应用。 编辑器提供一个 UI,用于:
- 创建和更新
.http
文件。 - 发送
.http
文件中指定的 HTTP 请求。 - 显示响应。
本文包含以下文档:
.http
文件语法。- 如何创建
.http
文件。 - 如何从
.http
文件发送请求。 - 在何处查找可配置的
.http
文件选项。 - 如何使用 Visual Studio 2022 终结点资源管理器在
.http
文件中创建请求。
.http
文件格式和编辑器受 Visual Studio Code REST 客户端扩展的启发。 Visual Studio 2022 .http
编辑器将 .rest
识别为相同文件格式的替代文件扩展名。
先决条件
- 安装了“ASP.NET 和 Web 部署”工作负载的 Visual Studio 2022 版本 17.8 或更高版本。
.http
文件语法
以下部分介绍 .http
文件语法。
请求
HTTP 请求的格式为 HTTPMethod URL HTTPVersion
,全部在一行上,其中:
HTTPMethod
是要使用的 HTTP 方法,例如:URL
是向其发送请求的 URL。 此 URL 可以包括查询字符串参数。 此 URL 不必指向本地 Web 项目。 它可以指向 Visual Studio 可以访问的任何 URL。HTTPVersion
是可选的,指定应使用的 HTTP 版本,即HTTP/1.1
、HTTP/2
或HTTP/3
。
通过使用行 ###
作为分隔符,文件可以包含多个请求。 以下示例在一个文件中显示了三个请求,说明了此语法:
GET https://localhost:7220/weatherforecast
###
GET https://localhost:7220/weatherforecast?date=2023-05-11&location=98006
###
GET https://localhost:7220/weatherforecast HTTP/3
###
请求标头
若要添加一个或多个标头,请将每个标头立即添加到请求行后其自己的行中。 不要在请求行与第一个标头之间或后续标头行之间包含任何空白行。 格式为 HeaderName: Value
,如以下示例所示:
GET https://localhost:7220/weatherforecast
Date: Wed, 27 Apr 2023 07:28:00 GMT
###
GET https://localhost:7220/weatherforecast
Cache-Control: max-age=604800
Age: 100
###
重要
调用使用标头进行身份验证的 API 时,请勿将任何机密提交到源代码存储库。 请参阅本文后面的支持存储机密的方法,例如 ASP.NET Core 用户机密、Azure Key Vault 和 DPAPI 加密。
请求正文
在空白行后面添加请求正文,如以下示例所示:
POST https://localhost:7220/weatherforecast
Content-Type: application/json
Accept-Language: en-US,en;q=0.5
{
"date": "2023-05-10",
"temperatureC": 30,
"summary": "Warm"
}
###
注释
以 #
或 //
开头的行是注释。 当 Visual Studio 发送 HTTP 请求时,将忽略这些行。
变量
以 @
开头的行使用语法 @VariableName=Value
定义变量。
可以在稍后在文件中定义的请求中引用变量。 通过用双大括号括起名称 {{
和 }}
来引用它们。 以下示例演示在请求中定义和使用的两个变量:
@hostname=localhost
@port=44320
GET https://{{hostname}}:{{port}}/weatherforecast
可以使用文件前面定义的其他变量的值来定义变量。 以下示例在请求中使用一个变量,而不是前面示例中所示的两个变量:
@hostname=localhost
@port=44320
@host={{hostname}}:{{port}}
GET https://{{host}}/api/search/tool
环境文件
若要在不同的环境中为变量提供不同的值,请创建名为 http-client.env.json
的文件。 在 .http
文件所在的同一目录中或其中一个父目录中找到该文件。 下面是环境文件的示例:
{
"dev": {
"HostAddress": "https://localhost:44320"
},
"remote": {
"HostAddress": "https://contoso.com"
}
}
环境文件是一个 JSON 文件,其中包含一个或多个命名环境,例如前面示例中的“dev”和“remote”。 每个命名环境都包含一个或多个变量,例如前面的示例中的 HostAddress
。 从环境文件中引用变量的方式与其他变量相同,如以下示例所示:
GET {{HostAddress}}/api/search/tool
发送请求时用于变量的值由 .http
文件编辑器右上角的环境选择器下拉列表确定。 以下屏幕截图显示了选择器:
环境文件不必位于项目文件夹中。 Visual Studio 在 .http
文件所在的文件夹中查找环境文件。 如果它不在该文件夹中,Visual Studio 会浏览父目录来查找它。 找到名为 http-client.env.json
的文件后,搜索将结束。 将使用最接近 .http
文件的文件。
创建或编辑 .http
文件后,可能需要关闭并重新打开项目,以查看环境选择器中反映的更改。 按 F6 选择环境选择器。
Visual Studio 在以下情况下显示警告:
.http
文件引用了未在.http
文件或环境文件中定义的变量。- 环境文件包含
.http
文件中未引用的变量。
在环境文件中定义的变量可以与 .http
文件中定义的变量相同,也可以不同。 如果在 .http
文件和环境文件中都定义了变量,则 .http
文件中的值将替代环境文件中的值。
特定于用户的环境文件
特定于用户的值是单个开发人员想要测试但不想与团队共享的任何值。 由于 http-client.env.json
文件默认签入到源代码管理中,因此不应将特定于用户的值添加到此文件。 而应将它们放在与 http-client.env.json
文件位于同一文件夹中的 http-client.env.json.user
文件中。 使用 Visual Studio 源代码管理功能时,应默认从源代码管理中排除以 .user
结尾的文件。
加载 http-client.env.json
文件时,Visual Studio 会查找同级 http-client.env.json.user
文件。 如果在 http-client.env.json
文件和 http-client.env.json.user
文件中的环境中都定义了变量,则 http-client.env.json.user
文件中的值优先级更高。
以下示例方案演示了特定于用户的环境文件工作原理。 假设 .http
文件包含以下内容:
GET {{HostAddress}}/{{Path}}
Accept: application/json
假设 http-client.env.json
文件包含以下内容:
{
"dev": {
"HostAddress": "https://localhost:7128",
"Path": "/weatherforecast"
},
"remote": {
"HostAddress": "https://contoso.com",
"Path": "/weatherforecast"
}
}
假设有一个特定于用户的环境文件,其中包含以下内容:
{
"dev": {
"Path": "/swagger/index.html"
}
}
当用户选择“开发”环境时,将向 https://localhost:7128/swagger/index.html
发送请求,因为 http-client.env.json.user
文件中的 Path
值会替代 http-client.env.json
文件中的值。
使用相同的环境文件,假设变量已在 .http
文件中定义:
@HostAddress=https://contoso.com
@Path=/weatherforecast
GET {{HostAddress}}/{{Path}}
Accept: application/json
在此场景中,“dev”环境请求将发送到 https://contoso.com/weatherforecast
,因为 .http
文件中的变量定义会替代环境文件定义。
ASP.NET Core 用户机密
若要从用户机密获取值,请使用与 ASP.NET Core 项目位于相同文件夹的环境文件。 在环境文件中,定义具有 provider
和 secretName
属性的变量。 将 provider
值设置为 AspnetUserSecrets
,并将 secretName
设置为所需用户机密的名称。 例如,以下环境文件定义一个名为 ApiKeyDev
的变量,它的值获取自 config:ApiKeyDev
用户机密:
{
"dev": {
"ApiKeyDev": {
"provider": "AspnetUserSecrets",
"secretName": "config:ApiKeyDev"
}
}
}
若要在 .http
文件中使用此变量,请像标准变量一样引用它。 例如:
GET {{HostAddress}}{{Path}}
X-API-KEY: {{ApiKeyDev}}
发送请求时,ApiKeyDev
机密的值位于 X-API-KEY 标头中。
键入 http
文件时,编辑器会显示变量名称的完成列表,但不会显示其值。
Azure Key Vault
Azure Key Vault 是 Azure 中可用于管理机密的多个密钥管理解决方案之一。 在当前支持 .http
文件的三种机密存储中,Key Vault 是跨不同用户共享机密的最佳选择。 其他两个选项(ASP.NET User Secrets 和 DPAPI 加密)不容易共享。
若要使用 Azure Key Vault 中的值,必须使用有权访问所需 Key Vault 的帐户登录到 Visual Studio。
使用元数据在环境文件中定义变量以访问机密。 在以下示例中,变量名为 AKVSecret
:
{
"dev": {
"AKVSecret": {
"provider": "AzureKeyVault",
"secretName": "SecretInKeyVault",
"resourceId": "/subscriptions/3a914c59-8175a9e0e540/resourceGroups/my-key-vault-rg/providers/Microsoft.KeyVault/vaults/my-key-vault-01182024"
}
}
}
AKVSecret
变量从 Azure Key Vault 拉取其值。 AKVSecret
上定义了以下属性:
名称 | 描述 |
---|---|
提供程序 | 对于密钥保管库,请始终使用 AzureKeyVault 。 |
secretName | 要提取的机密的名称。 |
resourceId | 要访问的特定密钥保管库的 Azure 资源 ID。 |
可以在 Azure 门户中找到 resourceId
属性的值。 转到“设置>属性”来查找它。 对于 secretName
,请使用 Azure 门户中“机密”页上显示的机密名称。
例如,下面的 .http
文件具有使用此机密值的请求。
GET {{HostAddress}}{{Path}}
X-AKV-SECRET: {{akvSecret}}
DPAPI 加密
Windows 上的数据保护 API (DPAPI) 可用于加密敏感数据。 使用 DPAPI 加密数据时,加密的值始终特定于计算机,并且它们在 .http
文件中也特定于用户。 这些值无法与其他用户共享。
若要加密值,请使用以下控制台应用程序:
using System.Security.Cryptography;
using System.Text;
string stringToEncrypt = "Hello, World!";
byte[] encBytes = ProtectedData.Protect(Encoding.Unicode.GetBytes(stringToEncrypt), optionalEntropy: null, scope: DataProtectionScope.CurrentUser);
string base64 = Convert.ToBase64String(encBytes);
Console.WriteLine(base64);
前面的控制台应用程序引用了 System.Security.Cryptography.ProtectedData NuGet 包。 若要使加密值能够在 .http
文件中工作,请在加密时将范围设置为 DataProtectionScope.CurrentUser。 加密值是 base64 编码的字符串,可以复制并粘贴到环境文件中。
在环境文件中,创建一个具有 provider
和 value
属性的变量。 将 provider
设置为 Encrypted
,并将加密值设置为 value
。 例如,以下环境文件定义一个名为 dpapiValue
的变量,它的值获取自使用 DPAPI 加密的字符串。
{
"dev": {
"dpapiValue": {
"provider": "Encrypted",
"value": "AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA5qwfg4+Bhk2nsy6ujgg3GAAAAAACAAAAAAAQZgAAAAEAACAAAAAqNXhXc098k1TtKmaI4cUAbJVALMVP1zOR7mhC1RBJegAAAAAOgAAAAAIAACAAAABKu4E9WC/zX5LYZZhOS2pukxMTF9R4yS+XA9HoYF98GzAAAAAzFXatt461ZnVeUWgOV8M/DkqNviWUUjexAXOF/JfpJMw/CdsizQyESus2QjsCtZlAAAAAL7ns3u9mEk6wSMIn+KNsW/vdAw51OaI+HPVrt5vFvXRilTtvGbU/JnxsoIHj0Z7OOxlwOSg1Qdn60zEqmlFJBg=="
}
}
}
在上述环境文件中,dpapiValue
可以像任何其他变量一样在 .http
文件中使用。 例如:
GET {{HostAddress}}{{Path}}
X-DPAPI-Secret: {{dpapiSecret}}
发送此请求后,X-DPAPI-Secret 具有解密的机密值。
环境变量
若要获取环境变量的值,请使用 $processEnv
。 以下示例将 USERNAME 环境变量的值置于 X-UserName 标头中。
GET {{HostAddress}}{{Path}}
X-UserName: {{$processEnv USERNAME}}
如果试图使用 $processEnv
访问不存在的环境变量,.http
文件编辑器将显示一条错误消息。
.env
文件
若要获取 .env
文件中定义的变量的值,请使用 $dotenv
。 .env
文件必须位于项目文件夹中。 $dotenv
和 $processEnv
的格式相同。 例如,如果 .env
文件具有以下内容:
USERNAME=userFromDotenv
且 .http
文件包含此内容:
GET {{HostAddress}}{{Path}}
X-UserName: {{$dotEnv USERNAME}}
X-UserName
标头将具有“userFromDotenv”。
在编辑器中输入 $dotenv
时,它显示 .env
文件中定义的变量的完成情况。
注意
默认情况下,可能不会从源代码管理中排除 .env
文件,因此请谨慎避免签入任何机密值。
随机整数
若要生成随机整数,请使用 $randomInt
。 语法是 {{$randomInt [min max]}}
, min
和 max
值是可选的。
日期和时间
$datetime
生成 UTC 格式的datetime
字符串。 语法是{{$datetime [format] [offset option]}}
,其中格式和偏移选项是可选的。$localDatetime
在本地时区中生成datetime
字符串。 语法是{{$localDatetime [format] [offset option]}}
,其中格式和偏移选项是可选的。$timeStamp
生成 UTC 格式的timestamp
。timestamp
是从 Unix 时间戳开始所经过的秒数(UTC 时间)。 语法是{{$timestamp [offset option]}}
,其中偏移选项是可选的。
选项 [format]
是 rfc1123
、iso8601
或用引号表示的自定义格式。 例如:
GET https://httpbin.org/headers
X-CUSTOM: {{$datetime "dd-MM-yyyy"}}
X-ISO8601: {{$datetime iso8601}}
X-ISO8601L: {{$localDatetime iso8601}}
X-RFC1123: {{$datetime rfc1123}}
X-RFC1123L: {{$localDatetime rfc1123}}
以下是前面的示例生成的一些示例值:
{
"headers": {
"X-Custom": "17-01-2024",
"X-Iso8601": "2024-01-17T22:59:55.5345770+00:00",
"X-Iso8601L": "2024-01-17T14:59:55.5345770-08:00",
"X-Rfc1123": "Wed, 17 Jan 2024 22:59:55 GMT",
"X-Rfc1123L": "Wed, 17 Jan 2024 14:59:55 -08"
}
}
语法 [offset option]
采用 number
unit
形式,其中 number
是整数,unit
是以下值之一:
unit |
说明 |
---|---|
ms |
毫秒 |
s |
秒 |
m |
分钟 |
h |
时数 |
d |
日 |
w |
周 |
M |
数月 |
y |
年数 |
例如:
GET https://httpbin.org/headers
X-Custom-Minus-1-Year: {{$datetime "dd-MM-yyyy" -1 y}}
X-RFC1123-Plus-1-Day: {{$datetime rfc1123 1 d}}
X-Timestamp-Plus-1-Year: {{$timestamp 1 y}}
以下是前面的示例生成的一些示例值:
{
"headers": {
"X-Custom-Minus-1-Year": "17-01-2023",
"X-Rfc1123-Plus-1-Day": "Thu, 18 Jan 2024 23:02:48 GMT",
"X-Timestamp-Plus-1-Year": "1737154968"
}
}
前面的一些示例使用免费的开源网站 <httpbin.org>。 这是一个与 Microsoft 无关的第三方网站。 在这些示例中,它会返回一个响应正文,其中包含在请求中发送的标头。 有关使用此资源进行 API 测试的其他方法的信息,请参阅 httpbin.org 网站的 home。
不支持的语法
Visual Studio 2022 .http
文件编辑器不具备 Visual Studio Code REST 客户端扩展拥有的所有功能。 以下列表包含一些仅在 Visual Studio Code 扩展中可用的更重要的功能:
- 跨多行的请求行
- 命名请求
- 将文件路径指定为请求正文
- 使用 multipart/form-data 时正文的混合格式
- GraphQL 请求
- cURL 请求
- 复制/粘贴为 cURL
- 请求历史记录
- 将响应正文保存到文件
- 基于证书的身份验证
- 提示变量
- 自定义响应预览
- 每请求设置
创建 .http
文件
在“解决方案资源管理器”中,右键单击 ASP.NET Core 项目。
在上下文菜单中,选择“添加”>“新建项...”。
在“添加新项”对话框中,选择“ASP.NET Core”>“常规”。
选择“HTTP 文件”,然后选择“添加”。
发送 HTTP 请求
向
.http
文件添加至少一个请求并保存该文件。如果请求 URL 指向 localhost 和项目的端口,请在尝试向其发送请求之前运行项目。
选择直接位于要发送的请求上方的
Send Request
或Debug
链接。请求将发送到指定 URL,响应将显示在编辑器窗口右侧的单独窗格中。
.http
文件选项
可以配置 .http
文件行为的某些方面。 若要查看可用内容,请转到“工具”>“选项”>“文本编辑器”>Rest。 例如,可以在“高级”选项卡上配置超时设置。下面是“选项”对话框的屏幕截图:
使用终结点资源管理器
终结点资源管理器是一个工具窗口,显示 Web API 定义的所有终结点。 借助该工具,可使用 .http
文件将请求发送到终结点。
终结点资源管理器显示的初始终结点集是静态地发现的。 有些终结点无法被静态地发现。 例如,在类库项目中定义的终结点直到运行时才能被发现。 运行或调试 Web API 时,Visual Studio 版本 17.11 预览版还会在运行时动态地发现终结点,并将这些终结点添加到终结点资源管理器。
打开终结点资源管理器
选择“查看”>“其他 Windows”>“终结点资源管理器”。
向 .http
文件添加请求
在“终结点资源管理器”中右键单击请求,然后选择“生成请求”。
- 如果存在项目名用作文件名的
.http
文件,则会将请求添加到该文件。 - 否则,会创建项目名用作文件名的
.http
文件,并且将请求添加到该文件。
前面的屏幕截图显示了由最小 API 项目模板定义的终结点。 以下示例显示为所选终结点生成的请求:
GET {{WebApplication1_HostAddress}}/weatherforecast/
Accept: application/json
###
如本文前面所述发送请求。