ASP.NET
JSON
Deserialization
Programming
Dictionary<string
string>

How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If the incoming JSON is a flat object with string values, deserializing to Dictionary<string, string> in ASP.NET is straightforward. The main complication is that real clients often send numbers, booleans, or nested objects, which no longer match a strict string-to-string dictionary.

So the real first step is to define the expected JSON shape. If the payload is truly key-value string metadata, a dictionary is fine. If the data has structure, a typed model is usually better.

The JSON Shape Must Match

A direct Dictionary<string, string> mapping expects JSON like this:

json
1{
2  "env": "prod",
3  "region": "us-east-1"
4}

That shape is simple: one object, string keys, string values.

If the values are numbers or nested objects, direct deserialization may fail or may require custom conversion logic.

System.Text.Json Example

In modern .NET, System.Text.Json is the usual default serializer.

csharp
1using System;
2using System.Collections.Generic;
3using System.Text.Json;
4
5var json = "{\"env\":\"prod\",\"region\":\"us-east-1\"}";
6var data = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
7
8Console.WriteLine(data?["env"]);

That is enough when the JSON is already a flat string map.

ASP.NET Controller Model Binding

In ASP.NET Core, the framework can bind the request body directly to a dictionary parameter.

csharp
1using Microsoft.AspNetCore.Mvc;
2using System.Collections.Generic;
3
4[ApiController]
5[Route("api/config")]
6public class ConfigController : ControllerBase
7{
8    [HttpPost("update")]
9    public IActionResult Update([FromBody] Dictionary<string, string> payload)
10    {
11        if (payload == null || payload.Count == 0)
12            return BadRequest("Payload cannot be empty");
13
14        return Ok(new { keys = payload.Keys });
15    }
16}

This is concise and works well when the set of keys is intentionally dynamic.

Handling Non-String Values Explicitly

If clients may send values that are not strings, you need to decide on a policy. One option is to parse the JSON manually and convert all values to strings deliberately.

csharp
1using System;
2using System.Collections.Generic;
3using System.Text.Json;
4
5string json = "{\"retries\":3,\"enabled\":true,\"name\":\"worker\"}";
6using var doc = JsonDocument.Parse(json);
7
8var result = new Dictionary<string, string>();
9foreach (var prop in doc.RootElement.EnumerateObject())
10{
11    result[prop.Name] = prop.Value.ToString();
12}
13
14Console.WriteLine(result["retries"]);

This makes the conversion rule explicit instead of relying on whatever a serializer might do by default.

When a Dictionary Is the Wrong Model

A dictionary is fine for metadata, dynamic form values, or user-defined key-value settings. It is a poor fit when the payload has a fixed domain shape.

For example, this is better modeled as a class than a dictionary:

json
1{
2  "name": "worker",
3  "enabled": true,
4  "retries": 3
5}

If the keys are known in advance, a typed model gives you validation, clearer documentation, and better error messages.

Common Pitfalls

A common mistake is trying to deserialize nested JSON directly into Dictionary<string, string>. The shape simply does not match.

Another issue is assuming all clients will send strings because the server wants strings. Real clients often send booleans and numbers naturally.

Developers also sometimes use a dictionary for payloads that really deserve a structured DTO. That throws away schema clarity for no real benefit.

Finally, dynamic payloads still need validation. A dictionary is easy to deserialize, but unsafe keys and unexpected values can still create downstream problems.

Summary

  • A flat JSON object with string values maps cleanly to Dictionary<string, string>.
  • In ASP.NET, controller model binding can accept that dictionary directly.
  • If values may be non-strings, convert them explicitly or switch to a typed model.
  • Use dictionaries only when the key set is intentionally dynamic.
  • If the payload has a stable schema, a dedicated DTO is usually the better design.

Course illustration
Course illustration

All Rights Reserved.