ASP.NET Web API (.NET Framework) · Quality & Delivery

IIS Deployment

Web API 2 apps live on IIS, Windows Server’s web server. Deploying means publishing the compiled site, configuring an application pool and a site, and swapping in production settings.

Advanced 5 min Lesson 34 of 36Covers ASP.NET Web API 2.2 on .NET Framework 4.8.
Before you start:Secure API Design
0/36 in ASP.NET Web API
On this page · 5 min · Advanced

Learning objectives#

  • Prepare a Windows server with IIS and ASP.NET 4.8
  • Publish the project with release settings
  • Use Web.config transforms for environment settings
  • Configure the app pool, HTTPS binding and database access

Explanation#

On the server, enable IIS with ASP.NET 4.8 (Server Manager → Web Server (IIS) → Application Development → ASP.NET 4.8). Install URL Rewrite and Dynamic Compression if you use them.

Publish from Visual Studio (Publish → Folder or Web Deploy) or from the command line with MSBuild. The output contains bin\, Global.asax and the transformed Web.config — no .cs files.

Web.config transforms (Web.Release.config) replace values at publish time: connection strings, app settings, debug="false". Keep real secrets out of Git by applying them on the build server or the server itself.

Create an application pool: .NET CLR Version v4.0, Managed Pipeline Integrated. Each API gets its own pool (and identity, IIS APPPOOL\ShopApi) so a crash or recycle affects only that app.

Create the site (or an application under an existing site), bind HTTPS with a certificate, and give the app pool identity read access to the folder and write access to App_Data if needed.

For SQL Server with Integrated Security, create a login for the app pool identity (or a domain service account) with least privilege.

Syntax#

Shell Illustrative
# Build and publish to a folder (Developer Command Prompt for VS)
msbuild ShopApi.csproj /p:Configuration=Release /p:DeployOnBuild=true /p:PublishProfile=FolderProfile


# On the server: create the app pool and site with appcmd
%windir%\system32\inetsrv\appcmd add apppool /name:ShopApi /managedRuntimeVersion:v4.0 /managedPipelineMode:Integrated
%windir%\system32\inetsrv\appcmd add site /name:ShopApi /physicalPath:D:\sites\ShopApi /bindings:https/*:443:api.shop.com
%windir%\system32\inetsrv\appcmd set app "ShopApi/" /applicationPool:ShopApi

Code example: Web.Release.config — production values applied at publish#

Razor / MarkupWeb.Release.config Illustrative
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">


  <connectionStrings>
    <add name="ShopDb"
         connectionString="Server=sql-prod01;Database=Shop;Integrated Security=True;"
         xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
  </connectionStrings>


  <appSettings>
    <add key="Cors:Origins" value="https://shop.example.com"
         xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
    <add key="Environment" value="Production"
         xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
  </appSettings>


  <system.web>
    <compilation xdt:Transform="RemoveAttributes(debug)" />
  </system.web>


</configuration>
Expected output
When publishing in Release, Visual Studio/MSBuild merges this file into Web.config: the ShopDb connection string points to sql-prod01, CORS allows only the production site, Environment becomes Production, and debug="true" is removed so IIS compiles optimised code and hides debug output.

This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.

Step-by-step explanation#

  1. xdt:Locator="Match(name)" finds the connection string with the same name in Web.config.
  2. xdt:Transform="SetAttributes" replaces only the attributes listed (connectionString, value).
  3. RemoveAttributes(debug) turns off debug compilation in production.
  4. appcmd creates an isolated application pool and an HTTPS site pointing at the published folder.
  5. The pool identity IIS APPPOOL\ShopApi is what SQL Server sees with Integrated Security.

Real-world use case#

A team deploys to two IIS servers behind a load balancer with Web Deploy from Azure DevOps. The pipeline applies Web.Release.config, injects the SQL password from a secret variable, takes one server out of rotation at a time, and runs smoke tests after each.

Common mistakes#

Deploying with debug="true"

Debug compilation is slower, uses more memory and can leak details. Make sure the Release transform removes it.

Wrong app pool settings

.NET CLR “No Managed Code” or Classic pipeline breaks Web API. Use v4.0 and Integrated.

500.19 errors after deploy

Usually a Web.config section that needs an IIS module (URL Rewrite, compression) not installed on the server. Install the module or remove the section.

Best practices#

  • One application pool per API
  • Publish Release builds only, with transforms
  • HTTPS binding with a valid certificate
  • Least-privilege identities for files and SQL

Remember this#

App pool: .NET CLR v4.0 + Integrated.

Web.Release.config: SetAttributes + Match(name/key).

IIS APPPOOL\YourPool is the identity SQL and the file system see.

Practice exercise#

Your task: Write a Web.Staging.config transform that sets the ShopDb connection string to Server=sql-staging;Database=Shop;Integrated Security=True; and Environment to Staging.

Need a hint?
Same structure as Web.Release.config with different values.
Show solution
Razor / Markup Illustrative
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings>
    <add name="ShopDb" connectionString="Server=sql-staging;Database=Shop;Integrated Security=True;"
         xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
  </connectionStrings>
  <appSettings>
    <add key="Environment" value="Staging" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
  </appSettings>
</configuration>

Mini quiz#

IIS Deployment quizMultiple choice Question 1 of 3

Which application pool settings does Web API 2 need?

Score so far: 0/0

Want more? Practise all ASP.NET Web API MCQs · ASP.NET Web API interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.