Route Options (MapRouteOptions)

Use MapRouteOptions / New-KrMapRouteOption to configure routes with richer metadata, different languages, and advanced behaviors.

Prerequisites: see Introduction.

Full source

File: pwsh/tutorial/examples/2.4-Route-Options.ps1

<#
    Sample Kestrun Server Configuration using MapRouteOptions class.
    These examples demonstrate how to use the MapRouteOptions class to configure routes in a Kestrun server.
    FileName: 2.4-Route-Options.ps1
#>

param(
    [int]$Port = 5000,
    [IPAddress]$IPAddress = [IPAddress]::Loopback
)

# Create a new Kestrun server
New-KrServer -Name 'Simple Server'

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

# Add the PowerShell runtime


# Enable Kestrun configuration
Enable-KrConfiguration

# Map the route
Add-KrMapRoute -Verbs Get -Pattern '/xml/{message}' -ScriptBlock {
    $message = Get-KrRequestRouteParam -Name 'message'
    Write-KrXmlResponse -InputObject @{ message = $message } -StatusCode 200
}

# YAML Route using MapRouteOption
Add-KrMapRoute -Options (New-KrMapRouteOption -Property @{
        Pattern = '/yaml'
        HttpVerbs = 'Get'
        ScriptCode = @{
            Code = {
                $message = Get-KrRequestCookie -Name 'message'
                Write-KrYamlResponse -InputObject @{ message = $message } -StatusCode 200
            }
            Language = 'PowerShell'
        }
        DisableAntiforgery = $true
    }
)

# JSON Route using MapRouteOption
$options = [Kestrun.Hosting.Options.MapRouteOptions]::new()
$options.Pattern = '/json'
$options.HttpVerbs = [Kestrun.Utilities.HttpVerb[]] @('get')
$options.ScriptCode = @{
    ScriptBlock = {
        $message = Get-KrRequestHeader -Name 'message'
        Write-KrJsonResponse -InputObject @{ message = $message } -StatusCode 200
    }
}
Add-KrMapRoute -Options $options

# Text Route using MapRouteOption and Pipeline
$txtOption = New-KrMapRouteOption -Property @{
    Pattern = '/txt'
    HttpVerbs = 'Get'
    ScriptCode = @{
        Code = @'
            var message= Context.Request.Query["message"];
            Context.Response.WriteTextResponse($"message = {message}");
'@
        Language = 'CSharp'
    }
}
 Add-KrMapRoute -Options $txtOption


# Start the server asynchronously
Start-KrServer

Step-by-step

  1. Base setup: Initialize-KrRoot, New-KrServer, Add-KrEndpoint, then Enable-KrConfiguration.
  2. XML route (PowerShell):
  3. YAML route (hashtable → New-KrMapRouteOption):
    • Compose an options object; set DisableAntiforgery = $true.
    • Pattern /yaml; since it has no {message} segment, route lookup returns $null.
  4. JSON route (explicit .NET object):
  5. Text route (C# code):
    • Options with Language = 'CSharp' and here-string code; access Context.Request.Query.
    • Use Context.Response.WriteTextResponse (C# extension method) to write plain text.
  6. Mixed styles: freely mix -ScriptBlock, hashtable + New-KrMapRouteOption, strongly-typed options, and C#/VB code.
  7. Language selection: set Language; PowerShell is assumed when -ScriptBlock is used.
  8. Antiforgery: use DisableAntiforgery to opt out per route if globally enabled.
  9. Retrieving data: route params, headers, and query (from C# example) as shown above.

When to use MapRouteOptions

Use MapRouteOptions when you need more than the simple -Verbs -Path -ScriptBlock shape:

  • Provide inline code in another language (Language, Code).
  • Configure route-level features like : DisableAntiforgery, CORS, or OpenAPI metadata.
  • Programmatically build routes (e.g., in loops) using strongly typed objects.
  • Share a common options template and adjust per route.

For quick, minimal routes the simple Add-KrMapRoute -Verbs Get -Path ... -ScriptBlock {} form remains fine.

Try it

Save the sample locally so it’s easy to run. Copy the contents of pwsh/tutorial/examples/2.4-Route-Options.ps1 into a new file in an empty working folder (for example, route-options.ps1), then run:

# From your working folder
pwsh .\route-options.ps1

Invoke each route:

CURL examples:

curl http://127.0.0.1:5000/xml/HelloXml
curl -v -b "message=fromYaml" "http://127.0.0.1:5000/yaml?message=fromYaml"
curl -H "message: HelloHeader" http://127.0.0.1:5000/json
curl http://127.0.0.1:5000/txt?message=HelloQuery

Invoke-WebRequest examples:

Invoke-WebRequest -Uri 'http://127.0.0.1:5000/xml/HelloXml' | Select-Object -ExpandProperty Content
Invoke-WebRequest -Uri 'http://127.0.0.1:5000/json' -Headers @{ message = 'HelloHeader' } | Select-Object -ExpandProperty Content
Invoke-WebRequest -Uri 'http://127.0.0.1:5000/txt?message=HelloQuery' | Select-Object -ExpandProperty Content

$session = [Microsoft.PowerShell.Commands.WebRequestSession]::new()
$session.Cookies.Add((New-Object System.Net.Cookie("message", "fromYaml", "/", "127.0.0.1")))
Invoke-WebRequest -Uri "http://127.0.0.1:5000/yaml?message=fromYaml" -Method Get -WebSession $session | Select-Object -ExpandProperty Content

References

Troubleshooting

Symptom Cause Fix
$message is $null on /yaml Pattern lacks {message} Change pattern to /yaml/{message} or use query/header instead
Header message not found on /json Missing message header Add -H "message: value" or use Get-KrRequestRouteParam/query
C# route errors Typos or missing semicolon in here‑string Validate C# snippet; keep indentation simple
404 Not Found Route not mapped or verb mismatch Confirm verb list includes the HTTP method (e.g., GET)

Previous / Next

Go back to Route Parameters or continue to Route Groups.