C# and .NET examples · Azure Functions
Azure Functions Middleware: The .NET 6 Comparison
A side-by-side comparison of two Azure Functions v4 projects on .NET 6: one using isolated worker middleware (WithMiddleware, built on IFunctionsWorkerMiddleware) and one without middleware (WithoutMiddleware, an in-process function). Both expose a SendMessage HTTP POST endpoint that greets the caller by name, but the middleware version transforms the name to uppercase before the function handler runs.
In this guide: Get started · Walk through the example · Understand the details · Check the limits
✨ Features
Projects
| Project | Port | Description |
|---|---|---|
WithMiddleware |
7052 | Registers UppercaseNameMiddleware; name is uppercased in middleware before reaching the handler |
WithoutMiddleware |
7162 | In-process model (Microsoft.NET.Sdk.Functions), no middleware; the raw name field from the JSON body is used as-is |
This comparison also changes the hosting model: it is not a comparison of two otherwise identical apps with just one middleware registration removed. An isolated worker app can also run without custom middleware.
🚀 Quick start
Running Locally
From the repository root, use a separate terminal for each command group:
# With middleware
cd Middleware/Dotnet6/WithMiddleware
func start --port 7052
# Without middleware (separate terminal)
cd Middleware/Dotnet6/WithoutMiddleware
func start --port 7162
📦 Prerequisites and installation
Requirements
- .NET 6 SDK
- Azure Functions Core Tools v4
- A
local.settings.jsonin each project (not committed to source control)
Minimum local.settings.json (WithMiddleware)
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
}
}
For the in-process WithoutMiddleware project, set "FUNCTIONS_WORKER_RUNTIME": "dotnet" instead of "dotnet-isolated".
NuGet Packages (WithMiddleware)
| Package | Version |
|---|---|
Microsoft.Azure.Functions.Worker |
1.19.0 |
Microsoft.Azure.Functions.Worker.Extensions.Http |
3.0.13 |
Microsoft.Azure.Functions.Worker.Sdk |
1.14.0 |
Newtonsoft.Json |
13.0.1 |
WithoutMiddleware references only Microsoft.NET.Sdk.Functions 4.2.0.
💡 Usage
How the Middleware Works
UppercaseNameMiddleware implements IFunctionsWorkerMiddleware:
- Reads the HTTP request body as a string
- Parses it as JSON (
JObject) - Converts the
nameproperty value to uppercase (or sets it to"name not found"if absent) - Stores the updated
JObjectincontext.Items["updated_body"] - Resets the request body stream position
- Calls
next(context)to pass control to the function handler
The SendMessageFunction then reads context.Items["updated_body"] and returns Hello {name}.
# With middleware — name is returned in uppercase
curl -X POST http://localhost:7052/api/SendMessage \
-H "Content-Type: application/json" \
-d '{"name": "alice"}'
Response: Hello ALICE.
# Missing name field
curl -X POST http://localhost:7052/api/SendMessage \
-H "Content-Type: application/json" \
-d '{}'
Response: Hello name not found.
# Without middleware — name is used as-is
curl -X POST http://localhost:7162/api/SendMessage \
-H "Content-Type: application/json" \
-d '{"name": "alice"}'
Response: Hello, alice. This HTTP triggered function executed successfully. (with no name, it asks you to pass one).
🏗️ Architecture
Project Structure
Dotnet6/
├── WithMiddleware/
│ ├── Functions/
│ │ └── SendMessageFunction.cs # Reads updated_body from context.Items
│ ├── Middlewares/
│ │ └── UppercaseNameMiddleware.cs # Transforms name to uppercase
│ ├── Program.cs # Registers middleware
│ └── WithMiddleware.csproj
├── WithoutMiddleware/
│ ├── Functions/
│ │ └── SendMessageFunction.cs # Reads name directly from request body
│ └── WithoutMiddleware.csproj
└── readme.md
🧪 Development and testing
Build the two projects independently and compare the same valid-name request on ports 7052 and 7162. Also check missing names, malformed JSON and whether the selected host provides a seekable request stream. These checks were not executed against a running host in this review.
🛠️ Troubleshooting and limitations
Start Azurite for the development storage setting. The isolated middleware sets requestData.Body.Position = 0; a non-seekable body stream can fail at that line. It parses and logs the entire request body without an exception handler or sensitive-field redaction. The examples use Bash curl syntax; on PowerShell, use curl.exe with appropriate JSON quoting or Invoke-RestMethod.
🔗 Related documentation
Related Examples
- .NET 8 version with exception-handling middleware
- Azure Functions middleware overview
- Back to all C# and .NET code examples
Documentation links
Read all C# and .NET Code Examples guides online · Project overview · All developer projects