{"id":244709,"date":"2023-08-23T08:47:02","date_gmt":"2023-08-23T15:47:02","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/visualstudio\/?p=244709"},"modified":"2024-01-19T10:52:18","modified_gmt":"2024-01-19T18:52:18","slug":"safely-use-secrets-in-http-requests-in-visual-studio-2022","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/safely-use-secrets-in-http-requests-in-visual-studio-2022\/","title":{"rendered":"Safely use secrets in HTTP requests in Visual Studio 2022"},"content":{"rendered":"<p>In the 17.8 Preview 1 version of Visual Studio 2022 we have updated the <a href=\"https:\/\/learn.microsoft.com\/aspnet\/core\/test\/http-files?view=aspnetcore-8.0\">HTTP file editor<\/a> to enable you to externalize variables to make testing your Web APIs across different environments easier. This update also includes support to handle secrets in a secure fashion. To access these new features, you\u2019ll need to install 17.8 Preview 1, or later, which you can do with the link below.<\/p>\n<p><div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/visualstudio.microsoft.com\/vs\/preview\" target=\"_blank\">Download Visual Studio 2022 Preview<\/a><\/div><\/p>\n<p>In previous releases if you wanted to use a variable in an HTTP file in Visual Studio, the variable would have to be defined directly in the HTTP file itself. This makes it more difficult to test different environments with the same HTTP file, and it also makes it hard to exercise web APIs that require secrets. In this post you\u2019ll learn about how you can define variables in external file(s) and then reuse those variables across different HTTP files. You\u2019ll also learn the different ways that you can secure your secrets and reuse those in a secure way in HTTP files. Before we get to the secrets support let\u2019s take a look at the environment file support first.<\/p>\n<h2>Environment file overview<\/h2>\n<p>When working with <a href=\"https:\/\/learn.microsoft.com\/aspnet\/core\/test\/http-files?view=aspnetcore-8.0\">HTTP files<\/a> in Visual Studio 2022 you can define multiple HTTP requests that you can execute from within the IDE. In previous releases you were able to define variables that could be used throughout the file. In this release you can externalize variables so that you can define different sets of values, environments, to be used. This also enables you to use the same environments across different HTTP files.<\/p>\n<p>To support different environments, you can add an HTTP request environment file which has the filename <em>httpenv.json<\/em>. You can also store user-specific values in an <em>httpenv.json.user<\/em> file, but we will get to that later in this post. Before we get to the <em>httpenv.json<\/em> file, let\u2019s look at a small HTTP file that has a few requests defined.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">@TemplatesApi_HostAddress = localhost:44320\r\n@searchTerm=api\r\n@templatePackId=MadsKristensen.AspNetCore.Miniblog\r\n@numToSkip=5\r\n@numToTake=2\r\n\r\nGET https:\/\/{{TemplatesApi_HostAddress}}\/api\/search\/{{searchTerm}}\r\n###\r\nGET https:\/\/{{TemplatesApi_HostAddress}}\/api\/templatepack\/{{templatePackId}}\r\n###\r\nGET https:\/\/{{TemplatesApi_HostAddress}}\/api\/templatepack\/{{numToSkip}}\/{{numToTake}}\r\n###<\/code><\/pre>\n<p>In this file you can see that we\u2019ve defined a few variables, the lines that start with @ define the variables. Since these variables are defined in the file, it may be difficult to exercise this app across different environments. For example, if we want to test the API that is running locally, we will use the <em>localhost<\/em> address. To exercise an app that has been published to a public endpoint, we may want to use a public URL instead of <em>localhost<\/em>. Let\u2019s look at the first request that is defined in this sample.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">GET https:\/\/{{TemplatesApi_HostAddress}}\/api\/search\/{{searchTerm}}\r\n###<\/code><\/pre>\n<p>In this request we are using the following variables.<\/p>\n<ul>\n<li>TemplatesApi_HostAddress<\/li>\n<li>searchTerm<\/li>\n<\/ul>\n<p>Both variables have been defined at the top of this file. If we send the request in the HTTP editor, the values for those variables will always be what is defined in the file. Now we want to externalize these two variables so that we can test the API in different environments. We will create a file named <em>httpenv.json<\/em>. This file should be in the same folder as the HTTP file, or a folder above it. Visual Studio will look for that file in the folder where the HTTP file exists. If it&#8217;s not found, VS will look at through the parent directories to find it. When a file is found named <em>httpenv.json,<\/em> Visual Studio will stop searching for the file. The nearest file to the HTTP file found will be used. In this case I\u2019ll add the <em>httpenv.json<\/em> to the same folder where the HTTP file is. In this specific example I have placed this file in a folder where an ASP.NET Core Web API project exists. That&#8217;s required to access ASP.NET Core User Secrets which we will discuss soon, but you can place these files in any directories, you do not need a .NET project to use these files. The contents of the file are below.<\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">{\r\n  \"dev\": {\r\n    \"TemplatesApi_HostAddress\": \"localhost:44320\",\r\n    \"searchTerm\": \"wpf\"\r\n  },\r\n  \"remote\": {\r\n    \"TemplatesApi_HostAddress\": \"dotnetnew-api.azurewebsites.net\",\r\n    \"searchTerm\": \"mads\"\r\n  }\r\n}\r\n<\/code><\/pre>\n<p><strong>Note: Starting in 17.8 Preview 2, the names of the environment files will change to http-client.env.json and http-client.env.json.user. httpenv.json and httpenv.json.user will not be used after that.<\/strong><\/p>\n<p>In the <em>httpenv.json<\/em> file shown above we have defined two different environments, <em>dev<\/em> and <em>remote<\/em>. Both environments have defined the two variables that we discussed above. You can define any number of environments in these files. After editing the <em>httpenv.json<\/em> file you may need reload, or make an edit to, the http file for the environment file to be discovered. After adding this file, you should see the environments dropdown populated with the environments defined in the file. That is shown in the following image.<\/p>\n<p><img decoding=\"async\" width=\"1258\" height=\"653\" class=\"wp-image-244710\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-6.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-6.png 1258w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-6-300x156.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-6-1024x532.png 1024w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-6-768x399.png 768w\" sizes=\"(max-width: 1258px) 100vw, 1258px\" \/><\/p>\n<p>In the screenshot above you can see the environment selector, in the expanded state. You can see the two environments, dev and remote. Let\u2019s start by selecting the dev environment. You can use the keyboard shortcut F6 to access the environment picker in the HTTP editor. Now that we have defined those two variables in the environment file, you should remove those from the HTTP file. Variables defined directly in the HTTP file will always win over variables defined in the environment file. Let\u2019s switch the environment to <em>remote<\/em> and send the first request in the HTTP file. Below is the Request tab of the Response View after the request was sent.<\/p>\n<p><img decoding=\"async\" width=\"1918\" height=\"1079\" class=\"wp-image-244711\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-7.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-7.png 1918w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-7-300x169.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-7-1024x576.png 1024w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-7-768x432.png 768w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-7-1536x864.png 1536w\" sizes=\"(max-width: 1918px) 100vw, 1918px\" \/><\/p>\n<p>In the image above the important parts have been highlighted. You\u2019ll notice that the selected environment is <em>remote<\/em>. From the full URL that is shown on the Request tab we can see that the value for the <em>TemplatesApi_HostAddress<\/em> used was <em>dotnetnew-api.azurewebsites.net<\/em> and the value for <em>searchTerm<\/em> used was <em>wpf<\/em>. For the first request in the HTTP file, we can now easily switch from the <em>dev<\/em> environment which uses the localhost address and the remote environment which uses a public URL. Now we can move the other variables into the environment file so that we don\u2019t have any values hard coded in this file. The updated HTTP file and <em>httpenv.json<\/em> file are shown below.<\/p>\n<p>Updated HTTP file<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">GET https:\/\/{{TemplatesApi_HostAddress}}\/api\/search\/{{searchTerm}}\r\n###\r\n\r\nGET https:\/\/{{TemplatesApi_HostAddress}}\/api\/templatepack\/{{templatePackId}}\r\n###\r\n\r\nGET https:\/\/{{TemplatesApi_HostAddress}}\/api\/templatepack\/{{numToSkip}}\/{{numToTake}}\r\n###\r\n<\/code><\/pre>\n<p>Updated <em>httpenv.json<\/em> file<\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">{\r\n  \"dev\": {\r\n    \"TemplatesApi_HostAddress\": \"localhost:44320\",\r\n    \"searchTerm\": \"wpf\",\r\n    \"templatePackId\": \"Boxed.Templates\",\r\n    \"numToSkip\": \"3\",\r\n    \"numToTake\": \"2\"\r\n  },\r\n  \"remote\": {\r\n    \"TemplatesApi_HostAddress\": \"dotnetnew-api.azurewebsites.net\",\r\n    \"searchTerm\": \"wpf\",\r\n    \"templatePackId\": \"Boxed.Templates\",\r\n    \"numToSkip\": \"50\",\r\n    \"numToTake\": \"6\"\r\n  }\r\n}\r\n<\/code><\/pre>\n<p>As shown above, we have removed all the variables that were defined in the HTTP file and defined them in both environments in the <em>httpenv.json<\/em> file. The HTTP editor will remember that last used environment. If you switch to an environment that doesn\u2019t have a variable that\u2019s used in the HTTP file, you\u2019ll receive a warning in the HTTP editor. This can also happen if you don\u2019t have an environment selected but the HTTP file uses a variable that is not defined in the HTTP file. To see this in action, switch the environment to none as shown in the next screenshot.<\/p>\n<p><img decoding=\"async\" width=\"1241\" height=\"305\" class=\"wp-image-244712\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screen-shot-of-a-computer-program-description-a-1.png\" alt=\"A screen shot of a computer program Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screen-shot-of-a-computer-program-description-a-1.png 1241w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screen-shot-of-a-computer-program-description-a-1-300x74.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screen-shot-of-a-computer-program-description-a-1-1024x252.png 1024w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screen-shot-of-a-computer-program-description-a-1-768x189.png 768w\" sizes=\"(max-width: 1241px) 100vw, 1241px\" \/><\/p>\n<p>In the previous screenshot you can see the warnings that are being generated by the HTTP editor. In this case the cursor was hovering over the <em>TemplatesApi_HostAddress<\/em> variable usage. There are two warnings being shown here, one that the variable used is not defined and another indicating that the URL is not valid for an HTTP request. The subsequent requests in the file show similar warnings. When you select an environment from the dropdown, the warnings will go away. Let\u2019s move on to discuss user specific settings.<\/p>\n<h2>User specific settings<\/h2>\n<p>When making Web API requests you may need to define certain variables that are user specific and not meant to be shared with the team. This is different from using secrets which we will discuss soon. A user specific value is any value that an individual developer wants to test with but doesn\u2019t want to share with the team. Since the <em>httpenv.json<\/em> file will be checked in by default it wouldn\u2019t be appropriate to add user specific values to this file. Instead, you can create a file named <em>httpenv.json.user<\/em> that is in the same folder as the <em>httpenv.json<\/em> file. Files that end with <em>.user<\/em> should be excluded from source control by default when using the Visual Studio source control features. When the <em>httpenv.json<\/em> file is loaded, it will look for a sibling <em>httpenv.json.user<\/em> file. If a variable is defined in an environment in both the <em>httpenv.json<\/em> file and the <em>httpenv.json.user<\/em> file, the value in the <em>httpenv.json.user<\/em> file will win.<\/p>\n<p>Let\u2019s build on top of the previous example where we had a dev and remote environment where we defined a <em>searchTerm<\/em> to be used. Imagine that you\u2019re the developer investigating a bug in the API that handles the route <em>api\/search<\/em>. The bug only appears when the <em>searchTerm<\/em> is set to \u2018maui\u2019. In that case you want to send \u2018maui\u2019 for <em>searchTerm<\/em> but not impact your team by changing the value in the base <em>httpenv.json<\/em> file. We will add a new file named <em>httpenv.json.user<\/em> that is in the same folder as the <em>httpenv.json<\/em> file. In that file we will define the <em>searchTerm<\/em> value in the dev environment. Below you can see the contents of the <em>httpenv.json.user<\/em> file for this case.<\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">{\r\n  \"dev\": {\r\n    \"searchTerm\": \"maui\"\r\n  }\r\n}\r\n<\/code><\/pre>\n<p>In the <em>httpenv.json.user<\/em> file we have defined the new value for <em>searchTerm<\/em> in the dev environment. We only defined the value for the specific item that we want to override. Since we only need this value in the dev environment, we don\u2019t need to define any other values. We also don\u2019t need to define any other values that are present in the <em>httpenv.json<\/em> file. You can also add variables, and environments, in the <em>httpenv.json.user<\/em> file which don\u2019t exist in the <em>httpenv.json<\/em> file. Let\u2019s look at the result after we send this request. The Request tab in the Response View is shown below for this request.<\/p>\n<p><img decoding=\"async\" width=\"988\" height=\"536\" class=\"wp-image-244713\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-4.png\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-4.png 988w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-4-300x163.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-4-768x417.png 768w\" sizes=\"(max-width: 988px) 100vw, 988px\" \/><\/p>\n<p>In the above image we can see that \u2018maui\u2019 was used as the value for <em>searchTerm<\/em> instead of \u2018wpf\u2019. To extend this, you can define additional values in the user file as needed. As mentioned, the .user file should be excluded from source control, but you should always double check that before committing your changes.<\/p>\n<p>The order of precedence for the variables usage is below. Once a match is found that value will be used, and other sources ignored.<\/p>\n<ol>\n<li>Variable declared in the HTTP file<\/li>\n<li>Variable declared in the <em>httpenv.json.user<\/em> file<\/li>\n<li>Variable declared in the <em>httpenv.json<\/em> file<\/li>\n<\/ol>\n<p>When working across multiple environments, its best to avoid variables declared in the HTTP file unless you are sure those values will not change. Now that we have covered user specific values, let\u2019s look at how you can use secrets in a secure fashion in your HTTP requests.<\/p>\n<h2>Using secrets<\/h2>\n<p>When working with Web APIs its common to need to use a secret in a request. To support secrets in a secure fashion we have added support for accessing secrets in three different ways.<\/p>\n<ul>\n<li>Secrets in <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/app-secrets?view=aspnetcore-7.0&amp;tabs=windows\">ASP.NET Core user secrets<\/a><\/li>\n<li>Secrets encrypted with <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/security\/how-to-use-data-protection\">Windows DPAPI<\/a><\/li>\n<li>Secrets in <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/key-vault\/general\/overview\">Azure Key Vault<\/a><\/li>\n<\/ul>\n<p>When using a secret, the metadata for the secret can go in either the <em>httpenv.json.user<\/em> file or the <em>httpenv.json<\/em> file. From the three providers listed above the only one that is team friendly is Azure Key Vault. The other two providers a user specific and those should be declared in the <em>httpenv.json.user<\/em> file. Let\u2019s look at how these secrets can be defined. We will look at each of the providers listed above.<\/p>\n<h3>Using secrets from ASP.NET Core User Secrets<\/h3>\n<p>When using secrets in development, one option is to use <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/app-secrets?view=aspnetcore-7.0&amp;tabs=windows\">ASP.NET Core User Secrets<\/a>. Let\u2019s say that you have a secret named \u2018config:templatesApiKeyDev\u2019 in user secrets. To use a value from user secrets, the HTTP environment file needs to be in the same folder as the ASP.NET Core project you are using. To use the value defined in user secrets from the <em>httpenv.json<\/em> or <em>httpenv.json.user<\/em> file use the syntax below to define a new variable named \u2018templatesApiKey\u2019. Below is an updated version of the <em>httpenv.json.user<\/em> file which we used previously.<\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">{\r\n  \"dev\": {\r\n    \"searchTerm\": \"maui\",\r\n    \"templatesApiKey\": {\r\n      \"provider\": \"AspnetUserSecrets\",\r\n      \"secretName\": \"config:templatesApiKeyDev\"\r\n    }\r\n  }\r\n}\r\n<\/code><\/pre>\n<p>Here we have defined a new variable named templatesApiKey and configured it to look up the value for the secret in the user secrets. This uses a property, <em>provider<\/em>, which determines how the secret should be looked up. Currently we support three values for <em>provider<\/em>, which are below.<\/p>\n<ul>\n<li>AspnetUserSecrets<\/li>\n<li>AzureKeyVault<\/li>\n<li>Encrypted<\/li>\n<\/ul>\n<p>We will explore the other options for this value below. This is not currently extensible, but if you\u2019re interested in extending this, please let us know.<\/p>\n<p>Going back to the AspnetUserSecrets example, to use this variable in the HTTP file, reference it like you would a standard variable. As you are typing in the HTTP file you should see the variable, as well as its value in the Completion list. See the image below.<\/p>\n<p><img decoding=\"async\" width=\"839\" height=\"242\" class=\"wp-image-244714\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-5.png\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-5.png 839w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-5-300x87.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-5-768x222.png 768w\" sizes=\"(max-width: 839px) 100vw, 839px\" \/><\/p>\n<p>In the image you can see the variable in the completion list. <strong>Note:<\/strong> in this preview we display the secret value as well, but it will be masked in an upcoming update. The request that was added to the HTTP file is below.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">GET https:\/\/{{TemplatesApi_HostAddress}}\/api\/search\/{{searchTerm}}\r\nX-API-KEY: {{templatesApiKey}}\r\n\r\n###\r\n<\/code><\/pre>\n<p>After sending this request, we can inspect the value of the header being passed in on the Request tab in the Response View. The result is shown in the image below.<\/p>\n<p><img decoding=\"async\" width=\"825\" height=\"561\" class=\"wp-image-244715\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-8.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-8.png 825w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-8-300x204.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-8-768x522.png 768w\" sizes=\"(max-width: 825px) 100vw, 825px\" \/><\/p>\n<p>As expected, when the request was sent the value for the <em>X-API-KEY<\/em> header was <em>value-from-user-secrets<\/em> as expected. Now we have seen how you can use values from user secrets in the HTTP file. Let\u2019s look at the Azure Key Vault provider now.<\/p>\n<h3>Using secrets from Azure Key Vault<\/h3>\n<p><a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/key-vault\/general\/overview\">Azure Key Vault<\/a> is one of several key management solutions in Azure which can be used for secrets management as well as managing other artifacts securely. From the secrets stores that are currently support in the HTTP environment file, Key Vault is the best choice when sharing secrets across different users. The other two options are not easily shared. To use a value from Azure Key Vault we will need to define a new variable and add the correct metadata to access that secret. Below you\u2019ll see an updated version of the <em>httpenv.json.user<\/em> file which has a new variable that gets it value from Azure Key Vault.<\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">{\r\n  \"dev\": {\r\n    \"searchTerm\": \"maui\",\r\n    \"templatesApiKey\": {\r\n      \"provider\": \"AspnetUserSecrets\",\r\n      \"secretName\": \"config:templatesApiKeyDev\"\r\n    },\r\n    \"otherSecret\": {\r\n      \"provider\": \"AzureKeyVault\",\r\n      \"keyVaultName\": \"sayedapi-keyvault-01\",\r\n      \"secretName\": \"SayedSecretValue1\",\r\n      \"resourceId\": \"\/subscriptions\/21e74a87-523d-4a15-87e9-8c5eb2df7716\/resourceGroups\/sayed-api-demo1\"\r\n    }\r\n  }\r\n}\r\n<\/code><\/pre>\n<p>In the JSON file above we\u2019ve defined a new variable, <em>otherSecret<\/em>, which pulls its value from Azure Key Vault. The properties defined on <em>otherSecret<\/em> are summarized below.<\/p>\n<table>\n<tbody>\n<tr>\n<td><strong>Name<\/strong><\/td>\n<td><strong>Description<\/strong><\/td>\n<\/tr>\n<tr>\n<td>provider<\/td>\n<td>For Key Vault always use AzureKeyVault<\/td>\n<\/tr>\n<tr>\n<td>keyVaultName<\/td>\n<td>The name of the Key Vault that contains the secret. <strong>Note<\/strong>: in a future update this property may not be removed.<\/td>\n<\/tr>\n<tr>\n<td>secretName<\/td>\n<td>Name of the secret to extract.<\/td>\n<\/tr>\n<tr>\n<td>resourceId<\/td>\n<td>Azure Resource Id for the specific Key Vault to access.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>You can find the value for the <em>keyVaultName<\/em> and <em>resourceId<\/em> in the Azure Portal. Find the Key Vault that contains the secret you want to use. Then go to Settings &gt; Properties to find both the name and the <em>resourceId<\/em> to use. For <em>secretName<\/em>, that is the name of the secret that you\u2019ll find on the Secrets page in the Azure Portal. <strong>To access a secret in Azure Key Vault you must be signed into Visual Studio with an account which has access to the given Key Vault.<\/strong> Now that we\u2019ve gone over the support for Key Vault secrets, let\u2019s see it in action. Below is a new request that was added to the HTTP file to use this secret value. <strong>Note:<\/strong> the properties in the Azure Key Vault section may change in a future update.<\/p>\n<p>GET https:\/\/{{TemplatesApi_HostAddress}}\/api\/search\/{{searchTerm}}<\/p>\n<p>X-CUSTOM-SECRET: {{otherSecret}}<\/p>\n<p>###<\/p>\n<p><strong>NOTE: Starting in 17.9 the format for Azure Key Vault has been updated, use the syntax below. The keyVaultName property was removed and the resourceId property now contains the full resourceId URL from Azure which contains the key vault name.<\/strong><\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">\"otherSecret\": {\r\n  \"provider\": \"AzureKeyVault\",\r\n  \"secretName\": \"SayedSecretValue1\",\r\n  \"resourceId\": \"\/subscriptions\/21e74a87-523d-4a15-87e9-8c5eb2df5516\/resourceGroups\/sayed-api-demo1\/providers\/Microsoft.KeyVault\/vaults\/sayedapi-keyvault-01\"\r\n}<\/code><\/pre>\n<p>&nbsp;<\/p>\n<p>In this request we are passing a custom header, <em>X-CUSTOM-SECRET<\/em>, and populating its value from <em>otherSecret<\/em>. When this request is sent, we can look at the Request tab in the Response View to see the value for this header. That is shown in the image below.<\/p>\n<p><img decoding=\"async\" width=\"873\" height=\"446\" class=\"wp-image-244716\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-9.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-9.png 873w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-9-300x153.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-9-768x392.png 768w\" sizes=\"(max-width: 873px) 100vw, 873px\" \/><\/p>\n<p>In the above screenshot we can see that the value for <em>X-CUSTOM-HEADER<\/em> was set to <em>super-secret-here<\/em>, that is the value that is stored in Key Vault for this secret. Now that we have discussed the support for Azure Key Vault, let\u2019s move on to the only remaining secret support.<\/p>\n<h3>Using secrets encrypted with Windows DPAPI<\/h3>\n<p>When working on Windows there is a <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/standard\/security\/how-to-use-data-protection\">Data Protection API<\/a>, aka DPAPI, which can be used to encrypt sensitive data. This is a commonly used method to encrypt values which is used by many different applications, including ones shipped by Microsoft. In Visual Studio when you create a web publish profile, the password is encrypted with the Data Protection API and stored in a .user file. When encrypting values with DPAPI, the encrypted values are always machine specific and in the case of this usage it\u2019s also user specific. These values cannot be shared with other users. Below is an updated version of the <em>httpenv.json.user<\/em> file that now includes a secret encrypted with DPAPI.<\/p>\n<pre class=\"prettyprint language-json\"><code class=\"language-json\">{\r\n  \"dev\": {\r\n    \"searchTerm\": \"maui\",\r\n    \"templatesApiKey\": {\r\n      \"provider\": \"AspnetUserSecrets\",\r\n      \"secretName\": \"config:templatesApiKeyDev\"\r\n    },\r\n    \"otherSecret\": {\r\n      \"provider\": \"AzureKeyVault\",\r\n      \"keyVaultName\": \"sayedapi-keyvault-01\",\r\n      \"secretName\": \"SayedSecretValue1\",\r\n      \"resourceId\": \"\/subscriptions\/21e74a87-523d-4a15-87e9-8c5eb2df7716\/resourceGroups\/sayed-api-demo1\"\r\n    },\r\n    \"secretValue\": {\r\n      \"provider\": \"Encrypted\",\r\n      \"value\": \"AQAAANCMnd8BFdERjHoAwE\/Cl+sBAAAA5qwfg4+Bhk2nsy6ujgg3GAAAAAACAAAAAAAQZgAAAAEAACAAAAAqNXhXc098k1TtKmaI4cUAbJVALMVP1zOR7mhC1RBJegAAAAAOgAAAAAIAACAAAABKu4E9WC\/zX5LYZZhOS2pukxMTF9R4yS+XA9HoYF98GzAAAAAzFXatt461ZnVeUWgOV8M\/DkqNviWUUjexAXOF\/JfpJMw\/CdsizQyESus2QjsCtZlAAAAAL7ns3u9mEk6wSMIn+KNsW\/vdAw51OaI+HPVrt5vFvXRilTtvGbU\/JnxsoIHj0Z7OOxlwOSg1Qdn60zEqmlFJBg==\"\r\n    }\r\n  }\r\n}\r\n<\/code><\/pre>\n<p>The last entry is the one that we are discussing here. The value for <em>provider<\/em> is <em>Encrypted<\/em> and the value for <em>value<\/em> is the encrypted string. We don\u2019t currently have support for you to encrypt a value, but we will add that support soon. In the meantime, it\u2019s very easy to encrypt a value using the Data Protection API. A sample console application to encrypt the value is shown below.<\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">using System.Security.Cryptography;\r\nusing System.Text;\r\n\r\nstring stringToEncrypt = \"Hello, World!\";\r\nbyte[] encBytes = ProtectedData.Protect(Encoding.Unicode.GetBytes(stringToEncrypt), optionalEntropy: null, scope: DataProtectionScope.CurrentUser);\r\nstring base64 = Convert.ToBase64String(encBytes);\r\nConsole.WriteLine(base64);\r\n<\/code><\/pre>\n<p>The console application above requires the <a href=\"https:\/\/www.nuget.org\/packages\/System.Security.Cryptography.ProtectedData\/\">System.Security.Cryptography.ProtectedData<\/a> NuGet package to be referenced. For the encrypted value to work in the HTTP file, you must encrypt with the scope set to <em>DataProtectionScope.CurrentUser<\/em>. Later we will add support in Visual Studio 2022 so that you don\u2019t have to manually encrypt these values. Now that we have populated the <em>httpenv.json.user<\/em> file with the new secret, we can use it like how we did the other two secrets. A new request using this secret is shown below.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">GET https:\/\/{{TemplatesApi_HostAddress}}\/api\/search\/{{searchTerm}}\r\nX-CUSTOM-SECRET: {{secretValue}}\r\n\r\n###\r\n<\/code><\/pre>\n<p>When we send this request the value for the custom header will be displayed on the Request tab in the Response View. See the following image.<\/p>\n<p><img decoding=\"async\" width=\"871\" height=\"437\" class=\"wp-image-244717\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-10.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-10.png 871w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-10-300x151.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/a-screenshot-of-a-computer-description-automatica-10-768x385.png 768w\" sizes=\"(max-width: 871px) 100vw, 871px\" \/><\/p>\n<p>We can see that the secret value was passed in as expected. Now that we have discussed how to use the secrets in your HTTP request as well as secrets, let\u2019s move on to some of the other features that have been added to the HTTP editor in this release.<\/p>\n<h2>New support for HTTP file syntax<\/h2>\n<p>In my <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/web-api-development-in-visual-studio-2022\/\">last blog post related to the HTTP Editor<\/a> we mentioned that there is still a lot of syntax that the HTTP file has support for in the <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=humao.rest-client\">VS Code REST Client extension<\/a> that is missing from the Visual Studio 2022 support. In this release we have added some support for additional syntax. The list of new syntax that is supported is below.<\/p>\n<table>\n<tbody>\n<tr>\n<td><strong>Function<\/strong><\/td>\n<td><strong>Description<\/strong><\/td>\n<\/tr>\n<tr>\n<td>$randomInt<\/td>\n<td>Generates a random integer.<\/p>\n<p>Format when calling this is <em>{{$randomInt [min max]}}<\/em> where the <em>min<\/em> and <em>max<\/em> values are optional.<\/p>\n<p><strong>Note:<\/strong> we currently have a bug that always returns the <em>max<\/em> value when specifying <em>min<\/em> and <em>max<\/em> values. That will get fixed in an upcoming release.<\/td>\n<\/tr>\n<tr>\n<td>$datetime<\/td>\n<td>Generates a datetime string. Formats supported include ISO8601, RFC1123 or a custom format.<\/p>\n<p>Format when calling this is <em>{{$datetime rfc1123|iso8601|\u201ccustom format\u201d [offset option]<\/em>.<\/td>\n<\/tr>\n<tr>\n<td>$timestamp<\/td>\n<td>Generates a UTC timestamp. Default behavior generates a timestamp from the current time. With options you can generate an offset timestamp.<\/p>\n<p>Format when calling this is <em>{{$timestamp [offset option]}}<\/em>.<\/td>\n<\/tr>\n<tr>\n<td>$localdatetime<\/td>\n<td>Generates a datetime string in your local time zone.<\/p>\n<p>Format when calling this is <em>{{$localdatetime rfc1123|iso8601|\u201ccustom format\u201d [offset option]}}<\/em>.<\/td>\n<\/tr>\n<tr>\n<td>$processenv<\/td>\n<td>Returns the value of the provided process environment variable.<\/p>\n<p>Format when using this is <em>{{$processEnv envVarName}}<\/em>.<\/td>\n<\/tr>\n<tr>\n<td>$dotenv<\/td>\n<td>Returns the value of the provided variable in a <a href=\"https:\/\/github.com\/motdotla\/dotenv\">.env<\/a> file.<\/p>\n<p>Format when using this is <em>{{$dotenv variableName}}<\/em>.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>These are special variable declarations which will generate a value with the given parameters. We will first look at the first four and then cover the remaining two. Some of the following requests will use the free open-source website <a href=\"https:\/\/httpbin.org\/\">httpbin.org<\/a>. This is a third-party website and not affiliated with Microsoft. This is a great website to assist in your API development. Look at the homepage for how you can use this awesome resource beyond what I show here. The request below shows some examples of the first four functions from the table above.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">GET https:\/\/httpbin.org\/headers\r\nX-1RandomInt: {{$randomInt}}\r\nX-2DateTime: {{$datetime iso8601}} \r\nX-3DateTime: {{$datetime rfc1123}} \r\nX-4DateTime: {{$datetime rfc1123 1 d}} \r\nX-5DateTime: {{$datetime \"dd-MM-yyyy\" 1 y}}\r\nX-6TimeStamp:{{$timestamp}}\r\nX-7TimeStamp:{{$timestamp 1 y}}\r\nX-8LocalDateTime: {{$localDatetime rfc1123}}\r\nX-9LocalDateTime: {{$localDatetime iso8601}}\r\nX-10LocalDateTime: {{$localDatetime iso8601 1 y}}\r\n\r\n###\r\n<\/code><\/pre>\n<p>Before we go over everything that this request does, let\u2019s quickly look at the result of this request. The result is below.<\/p>\n<p><img decoding=\"async\" width=\"636\" height=\"569\" class=\"wp-image-244718\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-9.png\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-9.png 636w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-9-300x268.png 300w\" sizes=\"(max-width: 636px) 100vw, 636px\" \/><\/p>\n<p>In this sample I\u2019m calling the special variables to generate the values and then passing them into the headers of the request. I\u2019m doing this because this is the best way to demo this. You can also pass these values into the body of the request as well.<\/p>\n<p>We can see the value for X-1RandomInt is a random integer as expected. When calling <em>$randomInt<\/em> you can specific a min max value like this example <em>{{$randomInt 1 100}}<\/em> which should generate a random integer from 1 (inclusive) to 100 (exclusive). Unfortunately, we have a bug in this preview where this syntax will always return the max value specified. That\u2019s why I didn\u2019t include an example of that in the sample request above. We will fix this issue in an upcoming preview.<\/p>\n<p>In some cases, you may need to generate a datetime which is based on the current datetime but is offset by a specified amount of time. You can use option\/offset for this. Consider the sample <em>{{$datetime rfc1123 1 d}}<\/em>, this says, return the current datetime offset by 1 day. In the image above showing the response you can see that the value returned was one day ahead of the previous header which didn\u2019t have any offset\/option specified.<\/p>\n<p>When using <em>$datetime<\/em> to generate a datetime string, we need to specify the format of the string to return, either ISO8601 or RFC1123. The format string is required. This will return the current datetime in the specified format. You can also generate a datetime string which is offset from the current time using the offset and option parameters. The value for offset should be an integer and the value for the option parameter is shown in the table below.<\/p>\n<table>\n<tbody>\n<tr>\n<td><strong>Option<\/strong><\/td>\n<td><strong>Description<\/strong><\/td>\n<\/tr>\n<tr>\n<td>y<\/td>\n<td>Year<\/td>\n<\/tr>\n<tr>\n<td>M<\/td>\n<td>Month<\/td>\n<\/tr>\n<tr>\n<td>w<\/td>\n<td>Week<\/td>\n<\/tr>\n<tr>\n<td>d<\/td>\n<td>Day<\/td>\n<\/tr>\n<tr>\n<td>h<\/td>\n<td>Hour<\/td>\n<\/tr>\n<tr>\n<td>m<\/td>\n<td>Minute<\/td>\n<\/tr>\n<tr>\n<td>s<\/td>\n<td>Second<\/td>\n<\/tr>\n<tr>\n<td>ms<\/td>\n<td>Millisecond<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>These values for the option in the datetime variable are the same for the other datetime functions. Consider this example {{$datetime &#8220;dd-MM-yyyy&#8221; 1 y}}, in this case a datetime will be generated for 1 year from the time the request was sent and will be returned in the format dd-MM-yyyy. <strong>Note:<\/strong> in the current preview you should use lowercase strings for the option except for M for Month. In a later release this may change.<\/p>\n<p>The timestamp is seconds since the Unix Epoch in UTC time (<em>DateTimeOffset.ToUnixTimeSeconds()<\/em>).<\/p>\n<p>The <em>$localdatetime<\/em> is like <em>$datetime<\/em>, the difference being that <em>$localdatetime<\/em> returns a datetime in the current local time zone. <em>$datetime<\/em> returns the datetime in UTC. Now that we have covered <em>$randomInt<\/em> and the datetime variables let\u2019s move on to discuss the remaining two special variables.<\/p>\n<h3>$processEnv and $dotenv<\/h3>\n<p>When developing APIs as you exercise the API you may need to access environment variables or variables defined in a <a href=\"https:\/\/github.com\/motdotla\/dotenv\">.env<\/a> file. To access an environment variable, we can use $processEnv. For example, to get the value for the USERNAME environment variable use the following syntax {{$processEnv USERNAME}}. You can also get the value for an environment variable by using the value for another variable as the name of the environment variable. Look at the sample request below.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">GET https:\/\/httpbin.org\/headers\r\nX-1Username: {{$processEnv USERNAME}}\r\nX-2ApiSecret: {{$processEnv API_SECRET}}\r\n\r\n###\r\n<\/code><\/pre>\n<p>For the sample above, I have created an environment variable API_SECRET and set the value to \u2018mySecretValueHere\u2019.<\/p>\n<p><img decoding=\"async\" width=\"1108\" height=\"638\" class=\"wp-image-244719\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-10.png\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-10.png 1108w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-10-300x173.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-10-1024x590.png 1024w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-10-768x442.png 768w\" sizes=\"(max-width: 1108px) 100vw, 1108px\" \/><\/p>\n<p>When the request was sent the value for <em>X-1Username<\/em> was populated from the <em>USERNAME<\/em> environment variable, and the same happens for <em>X-2ApiSecret<\/em>. If you use $processEnv to try to access an environment variable which doesn\u2019t exist, you will get a warning in the HTTP editor. Now let\u2019s move on to discuss $dotenv.<\/p>\n<p>When using $processEnv you can get environment variables that are defined on the machine\/process. In some cases you may need to get the value for an variable that has been defined in a <a href=\"https:\/\/github.com\/motdotla\/dotenv\">.env<\/a> file. For these cases you can use the other special variable $dotenv. The format for using $dotenv is the same as $processEnv. I\u2019ve created a file named .env in the project folder with the following contents.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">USERNAME=sayedFromDotenv\r\nAPI_SECRET=secretFromDotenv\r\n<\/code><\/pre>\n<p>When using $dotenv you should see completions in the HTTP editor for all the variables defined. See the image below.<\/p>\n<p><img decoding=\"async\" width=\"970\" height=\"345\" class=\"wp-image-244720\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-11.png\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-11.png 970w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-11-300x107.png 300w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-11-768x273.png 768w\" sizes=\"(max-width: 970px) 100vw, 970px\" \/><\/p>\n<p>In the above image you can see that we are getting completions for the three variables that I defined in the .env file. Below is a request that we can use to try out $dotenv.<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">GET https:\/\/httpbin.org\/headers\r\nX-1Username: {{$dotenv USERNAME}}\r\nX-2ApiSecret: {{$dotenv API_SECRET}}\r\n\r\n###\r\n<\/code><\/pre>\n<p>When we send this request the result will be what\u2019s shown in the following image.<\/p>\n<p><img decoding=\"async\" width=\"628\" height=\"456\" class=\"wp-image-244721\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-12.png\" srcset=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-12.png 628w, https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2023\/08\/word-image-244709-12-300x218.png 300w\" sizes=\"(max-width: 628px) 100vw, 628px\" \/><\/p>\n<p>As expected, we get the value for USERNAME in X-1Username and the value for API_SECRET in X-2ApiSecret. When working with .env files remember that these files are typically NOT checked in and contain user specific values and even may contain secrets. This file may not be excluded from source control by default today, so be careful if you use these files to not check in any secret values. We\u2019ve covered all the updates in this release, so we will close out this post after the Resources section.<\/p>\n<h2>Resources<\/h2>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/aspnet\/core\/test\/http-files?view=aspnetcore-8.0\">Docs for using HTTP files in Visual Studio 2022<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/web-api-development-in-visual-studio-2022\/\">Recent blog post published by Sayed discussing Web API features in Visual Studio 2022<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/app-secrets?view=aspnetcore-7.0&amp;tabs=windows\">Safe storage of app secrets in development in ASP.NET Core | Microsoft Learn<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/key-vault\/general\/overview\">Azure Key Vault Overview &#8211; Azure Key Vault | Microsoft Learn<\/a><\/li>\n<\/ul>\n<h2>Closing<\/h2>\n<p>In this post we covered a lot of updates that have been added to the HTTP editor including support for multiple environments, how to use secrets securely and the new syntax that we support. As I mentioned in my <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/web-api-development-in-visual-studio-2022\/\">previous blog post<\/a> we still have a lot of work to bring the HTTP file experience to parity with the <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=humao.rest-client\">Visual Studio Code REST Client extension<\/a>. We will continue investing in this experience to improve the experience. From the items that I identified in my previous blog post the current priority is going to be adding support for taking a value from a request and passing it to a subsequent request. This will open a lot of scenarios for testing, and it\u2019s highly used in HTTP files found in GitHub.<\/p>\n<p>Most of the updates that we delivered in this release were inspired by feedback from users like yourself. You can share feedback with us via\u00a0<a href=\"https:\/\/developercommunity.visualstudio.com\/home\" target=\"_blank\" rel=\"noopener\">Developer Community<\/a>: report any bugs or issues via\u00a0<a href=\"https:\/\/docs.microsoft.com\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio\" target=\"_blank\" rel=\"noopener\">report a problem<\/a>\u00a0and share your\u00a0<a href=\"https:\/\/developercommunity.visualstudio.com\/report?space=8&amp;entry=suggestion\" target=\"_blank\" rel=\"noopener\">suggestions for new features<\/a>\u00a0or improvements to existing ones. You can also leave a comment here or reach out to Sayed on Twitter at\u00a0<a href=\"https:\/\/twitter.com\/sayedihashimi\" target=\"_blank\" rel=\"noopener\">@SayedIHashimi<\/a>.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the 17.8 Preview 1 version of Visual Studio 2022 we have updated the HTTP file editor to enable you to externalize variables to make testing your Web APIs across different environments easier. This update also includes support to handle secrets in a secure fashion. To access these new features, you\u2019ll need to install 17.8 [&hellip;]<\/p>\n","protected":false},"author":357,"featured_media":244710,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[155],"tags":[],"class_list":["post-244709","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-studio"],"acf":[],"blog_post_summary":"<p>In the 17.8 Preview 1 version of Visual Studio 2022 we have updated the HTTP file editor to enable you to externalize variables to make testing your Web APIs across different environments easier. This update also includes support to handle secrets in a secure fashion. To access these new features, you\u2019ll need to install 17.8 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/244709","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/357"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=244709"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/244709\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/244710"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=244709"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=244709"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=244709"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}