Content Format

Customize the error content type and HTML body with external templates and variables.

Full source

File: pwsh/tutorial/examples/17.5-StatusCodePages-ContentFormat.ps1

#
# Sample: Status Code Pages with Content Format
# This script demonstrates how to set up a Kestrun server with custom content type and body format.
# The server will show formatted error pages with placeholders for status codes.
# FileName: 17.5-StatusCodePages-ContentFormat.ps1
#
param(
    [int]$Port = 5000,
    [IPAddress]$IPAddress = [IPAddress]::Loopback # Use 'Loopback' for safety in tests/examples
)


Initialize-KrRoot -Path $PSScriptRoot

New-KrLogger | Set-KrLoggerLevel -Level Information |
    Add-KrSinkConsole | Register-KrLogger -Name 'console' -SetAsDefault

# Create a new Kestrun server
New-KrServer -Name 'Status Code Pages with Content Format Server'

# Add a listener on the specified port and IP address
Add-KrEndpoint -Port $Port -IPAddress $IPAddress

# Define custom HTML template with placeholder for status code
$htmlTemplatePath = Join-Path $PSScriptRoot 'Assets\wwwroot\statuscodepages\error-contentformat.html'
$htmlTemplate = Get-Content -Path $htmlTemplatePath -Raw

# Replace timestamp placeholder with current timestamp
$htmlTemplate = $htmlTemplate -replace '\{TIMESTAMP\}', (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')

# Enable status code pages with custom content type and body format
# The {0} placeholder will be replaced with the actual status code
Enable-KrStatusCodePage -ContentType 'text/html; charset=utf-8' -BodyFormat $htmlTemplate

# Enable Kestrun configuration
Enable-KrConfiguration

# Map a normal route with some styling
Add-KrMapRoute -Verbs Get -Pattern '/hello' -ScriptBlock {
    # Read HTML template from file
    $htmlPath = '.\Assets\wwwroot\statuscodepages\welcome-contentformat.html'
    Write-KrHtmlResponse -FilePath $htmlPath -StatusCode 200
}

# Map routes that trigger different status codes
Add-KrMapRoute -Verbs Get -Pattern '/notfound' -ScriptBlock {
    # Return empty response with 404 status to trigger custom error page
    $Context.Response.StatusCode = 404
}

Add-KrMapRoute -Verbs Get -Pattern '/error' -ScriptBlock {
    # Return empty response with 500 status to trigger custom error page
    $Context.Response.StatusCode = 500
}

Add-KrMapRoute -Verbs Get -Pattern '/forbidden' -ScriptBlock {
    # Return empty response with 403 status to trigger custom error page
    $Context.Response.StatusCode = 403
}

Add-KrMapRoute -Verbs Get -Pattern '/unauthorized' -ScriptBlock {
    # Return empty response with 401 status to trigger custom error page
    $Context.Response.StatusCode = 401
}

Write-Host "Server starting on http://$($IPAddress):$Port" -ForegroundColor Green
Write-Host 'Try these URLs:' -ForegroundColor Yellow
Write-Host "  http://$($IPAddress):$Port/hello        - Styled welcome page with test links" -ForegroundColor Cyan
Write-Host "  http://$($IPAddress):$Port/notfound     - Styled 404 error page" -ForegroundColor Cyan
Write-Host "  http://$($IPAddress):$Port/error        - Styled 500 error page" -ForegroundColor Cyan
Write-Host "  http://$($IPAddress):$Port/forbidden    - Styled 403 error page" -ForegroundColor Cyan
Write-Host "  http://$($IPAddress):$Port/unauthorized - Styled 401 error page" -ForegroundColor Cyan
Write-Host "  http://$($IPAddress):$Port/missing      - Styled 404 for unmapped route" -ForegroundColor Cyan

# Start the server asynchronously
Start-KrServer -CloseLogsOnExit

Step-by-step

  1. Logging: Register a console logger.
  2. Template: Load HTML and inject runtime variables (e.g., timestamp).
  3. Middleware: Enable with -ContentType and -BodyFormat.
  4. Routes: Map /hello and demo routes for 404/500/403/401.
  5. Start: Apply configuration and start the server.

Try it

curl -i http://127.0.0.1:5000/hello
curl -i http://127.0.0.1:5000/notfound
curl -i http://127.0.0.1:5000/error
curl -i http://127.0.0.1:5000/forbidden
curl -i http://127.0.0.1:5000/unauthorized

PowerShell equivalents:

Invoke-WebRequest -Uri http://127.0.0.1:5000/hello | Select-Object StatusCode, Content
Invoke-WebRequest -Uri http://127.0.0.1:5000/notfound    -SkipHttpErrorCheck | Select-Object StatusCode, Content | Format-List
Invoke-WebRequest -Uri http://127.0.0.1:5000/error       -SkipHttpErrorCheck | Select-Object StatusCode, Content | Format-List
Invoke-WebRequest -Uri http://127.0.0.1:5000/forbidden   -SkipHttpErrorCheck | Select-Object StatusCode, Content | Format-List
Invoke-WebRequest -Uri http://127.0.0.1:5000/unauthorized -SkipHttpErrorCheck | Select-Object StatusCode, Content | Format-List

Troubleshooting

Symptom Likely cause Fix
Literal {0} appears in output Format string not applied Use -BodyFormat with {0} placeholder for status code
HTML not rendered Content type mismatch Set -ContentType 'text/html; charset=utf-8'
Time or variables not shown Variable not provided Double-check template variables and their scope

References


Previous / Next

Previous: Custom Handler (C# Inline) Next: Redirects