{"id":2245,"date":"2025-04-30T18:08:51","date_gmt":"2025-04-30T18:08:51","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=2245"},"modified":"2025-04-30T18:08:55","modified_gmt":"2025-04-30T18:08:55","slug":"building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/","title":{"rendered":"Building Custom JSON Serialization Logic Using Utf8JsonWriter and Utf8JsonReader"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">1. Introduction to JSON Serialization in .NET<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">JSON has become the lingua franca of modern software systems. Whether you&#8217;re building APIs, consuming web services, or storing configuration data, chances are you&#8217;re dealing with JSON. In the .NET ecosystem, handling JSON has become increasingly streamlined\u2014thanks to the evolution of <code>System.Text.Json<\/code>, which provides a high-performance, low-allocation alternative to older libraries like Newtonsoft.Json.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At a glance, serialization (converting an object into JSON) and deserialization (converting JSON back into an object) seem straightforward. For many standard use cases, using <code>JsonSerializer.Serialize()<\/code> and <code>JsonSerializer.Deserialize&lt;T&gt;()<\/code> will get the job done with minimal effort. But real-world applications often introduce complexity: custom data formats, performance constraints, conditional fields, or models that don\u2019t match the exact JSON schema you&#8217;re working with.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s where lower-level tools like <code>Utf8JsonWriter<\/code> and <code>Utf8JsonReader<\/code> come in. They give you precise control over the serialization process\u2014letting you manually write and read JSON tokens in a highly optimized way. Instead of relying on reflection and automatic mapping, you define exactly how data flows to and from JSON, one token at a time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This tutorial is for developers who are ready to go beyond the default serializer and need fine-tuned control over their JSON logic. Whether you&#8217;re building a high-throughput system, interfacing with third-party APIs with non-standard formats, or just want to squeeze every drop of performance out of your app, understanding <code>Utf8JsonWriter<\/code> and <code>Utf8JsonReader<\/code> can be a game-changer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the sections that follow, we\u2019ll break down how to use these tools from the ground up, starting with how to write basic JSON manually, and moving toward full custom serialization and deserialization logic for complex .NET objects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Overview of Utf8JsonWriter and Utf8JsonReader (\u2248250 words)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When working with JSON in .NET, the <code>System.Text.Json<\/code> namespace gives you more than just high-level serialization methods\u2014it also includes two powerful low-level APIs: <code>Utf8JsonWriter<\/code> and <code>Utf8JsonReader<\/code>. These are designed for developers who need full control over JSON input and output, especially in performance-critical or non-standard scenarios.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Utf8JsonWriter<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Utf8JsonWriter<\/code> is a forward-only, high-performance writer that emits JSON directly to a <code>Stream<\/code> or <code>IBufferWriter&lt;byte&gt;<\/code>. It writes UTF-8 encoded text, which makes it particularly efficient for web applications and microservices where every millisecond and byte counts. You use it by explicitly writing each JSON token\u2014start object, property name, value, array start, and so on. This approach avoids reflection, unnecessary allocations, and the overhead of generic serialization.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Utf8JsonReader<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">On the flip side, <code>Utf8JsonReader<\/code> is a forward-only reader that parses UTF-8 JSON data into a stream of tokens. Instead of deserializing an entire object automatically, you manually navigate through the tokens and extract values as needed. This gives you unmatched flexibility\u2014for example, you can skip irrelevant fields, handle unexpected data gracefully, or map flat JSON into deeply nested models.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These two classes are intentionally low-level and minimal by design. They don\u2019t manage state for you, nor do they build object graphs. But that\u2019s exactly what makes them so powerful\u2014they give you raw access to the data and trust you to manage the logic.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Setting Up the Development Environment (\u2248150 words)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before diving into code, let\u2019s set up a clean development environment to experiment with <code>Utf8JsonWriter<\/code> and <code>Utf8JsonReader<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisites<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Make sure you have the following installed:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>.NET 6.0 or later<\/strong> \u2013 These APIs are available in <code>System.Text.Json<\/code>, which ships with .NET Core 3.0 and above, but .NET 6+ is recommended for improved performance and features.<\/li>\n\n\n\n<li><strong>Visual Studio 2022<\/strong>, <strong>Rider<\/strong>, or <strong>VS Code<\/strong> \u2013 Any modern IDE that supports C# will work.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Creating the Project<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Open your terminal or IDE and create a new console application:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">dotnet <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">console<\/span> -n JsonSerializationDemo\ncd JsonSerializationDemo\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">No additional NuGet packages are required since <code>System.Text.Json<\/code> is part of the base class library.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Optional Setup<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To make testing easier, you can add the following NuGet package for debugging output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">dotnet<\/span> <span class=\"hljs-selector-tag\">add<\/span> <span class=\"hljs-selector-tag\">package<\/span> <span class=\"hljs-selector-tag\">Microsoft<\/span><span class=\"hljs-selector-class\">.Extensions<\/span><span class=\"hljs-selector-class\">.Logging<\/span><span class=\"hljs-selector-class\">.Console<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This setup gives you a clean slate to focus on hands-on examples. Next, we&#8217;ll get into the basics of writing JSON manually using <code>Utf8JsonWriter<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Understanding Utf8JsonWriter<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At first glance, manually writing JSON might sound tedious\u2014but <code>Utf8JsonWriter<\/code> makes it surprisingly straightforward. It\u2019s a low-level, high-performance API that lets you build JSON directly, token by token, with full control over structure, formatting, and data types.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How It Works<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Utf8JsonWriter<\/code> writes JSON to an <code>IBufferWriter&lt;byte&gt;<\/code>, commonly backed by a <code>MemoryStream<\/code>. It\u2019s forward-only and writes raw UTF-8 encoded bytes, which keeps it fast and efficient. You don\u2019t deal with strings unless you want to, and there\u2019s no reflection overhead.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Setup<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s a minimal example of using <code>Utf8JsonWriter<\/code> to serialize a simple object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">using System;\nusing System.IO;\nusing System.Text.Json;\n\n<span class=\"hljs-keyword\">var<\/span> stream = <span class=\"hljs-keyword\">new<\/span> MemoryStream();\n<span class=\"hljs-keyword\">var<\/span> writer = <span class=\"hljs-keyword\">new<\/span> Utf8JsonWriter(stream, <span class=\"hljs-keyword\">new<\/span> JsonWriterOptions { Indented = <span class=\"hljs-literal\">true<\/span> });\n\nwriter.WriteStartObject();\nwriter.WriteString(<span class=\"hljs-string\">\"name\"<\/span>, <span class=\"hljs-string\">\"Alice\"<\/span>);\nwriter.WriteNumber(<span class=\"hljs-string\">\"age\"<\/span>, <span class=\"hljs-number\">30<\/span>);\nwriter.WriteBoolean(<span class=\"hljs-string\">\"isActive\"<\/span>, <span class=\"hljs-literal\">true<\/span>);\nwriter.WriteEndObject();\nwriter.Flush();\n\nstring json = System.Text.Encoding.UTF8.GetString(stream.ToArray());\nConsole.WriteLine(json);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><strong>Output:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json\">{\n  <span class=\"hljs-attr\">\"name\"<\/span>: <span class=\"hljs-string\">\"Alice\"<\/span>,\n  <span class=\"hljs-attr\">\"age\"<\/span>: <span class=\"hljs-number\">30<\/span>,\n  <span class=\"hljs-attr\">\"isActive\"<\/span>: <span class=\"hljs-literal\">true<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This example shows how each field is explicitly written using a method tailored to its type.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Writing Arrays<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You can also write arrays easily:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">writer<\/span><span class=\"hljs-selector-class\">.WriteStartArray<\/span>(\"<span class=\"hljs-selector-tag\">tags<\/span>\");\n<span class=\"hljs-selector-tag\">writer<\/span><span class=\"hljs-selector-class\">.WriteStringValue<\/span>(\"<span class=\"hljs-selector-tag\">developer<\/span>\");\n<span class=\"hljs-selector-tag\">writer<\/span><span class=\"hljs-selector-class\">.WriteStringValue<\/span>(\"<span class=\"hljs-selector-tag\">blogger<\/span>\");\n<span class=\"hljs-selector-tag\">writer<\/span><span class=\"hljs-selector-class\">.WriteEndArray<\/span>();\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This would result in:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-string\">\"tags\"<\/span>: &#91;<span class=\"hljs-string\">\"developer\"<\/span>, <span class=\"hljs-string\">\"blogger\"<\/span>]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Nesting Objects<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nested structures are handled by chaining calls:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">writer.WriteStartObject(<span class=\"hljs-string\">\"address\"<\/span>);\nwriter.WriteString(<span class=\"hljs-string\">\"city\"<\/span>, <span class=\"hljs-string\">\"Seattle\"<\/span>);\nwriter.WriteString(<span class=\"hljs-string\">\"zip\"<\/span>, <span class=\"hljs-string\">\"98101\"<\/span>);\nwriter.WriteEndObject();\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Which produces:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-string\">\"address\"<\/span>: {\n  <span class=\"hljs-string\">\"city\"<\/span>: <span class=\"hljs-string\">\"Seattle\"<\/span>,\n  <span class=\"hljs-string\">\"zip\"<\/span>: <span class=\"hljs-string\">\"98101\"<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Key Takeaways<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use the correct <code>WriteX<\/code> methods based on data type.<\/li>\n\n\n\n<li>Always match <code>WriteStartObject<\/code> with <code>WriteEndObject<\/code>, and <code>WriteStartArray<\/code> with <code>WriteEndArray<\/code>.<\/li>\n\n\n\n<li>Call <code>Flush()<\/code> to ensure all data is written to the output stream.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">5. Understanding Utf8JsonReader<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Just as <code>Utf8JsonWriter<\/code> gives you precise control over writing JSON, <code>Utf8JsonReader<\/code> offers a fast and memory-efficient way to read and parse JSON. It\u2019s a forward-only, read-only parser that processes UTF-8 encoded text as a stream of tokens. This design makes it ideal for high-performance scenarios where allocating full object graphs isn\u2019t necessary\u2014or even possible.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How It Works<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Utf8JsonReader<\/code> reads a <code>ReadOnlySpan&lt;byte&gt;<\/code> or <code>ReadOnlySequence&lt;byte&gt;<\/code> containing JSON text. It doesn&#8217;t create objects or deserialize types for you\u2014instead, it exposes a sequence of tokens (e.g., <code>StartObject<\/code>, <code>PropertyName<\/code>, <code>String<\/code>, <code>EndObject<\/code>) that you can read and act on manually.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Basic Usage Example<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s say we want to read the following JSON:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json\">{\n  <span class=\"hljs-attr\">\"name\"<\/span>: <span class=\"hljs-string\">\"Alice\"<\/span>,\n  <span class=\"hljs-attr\">\"age\"<\/span>: <span class=\"hljs-number\">30<\/span>,\n  <span class=\"hljs-attr\">\"isActive\"<\/span>: <span class=\"hljs-literal\">true<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s how we could parse it:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">using System;\nusing System.Text;\nusing System.Text.Json;\n\n<span class=\"hljs-keyword\">var<\/span> json = <span class=\"hljs-string\">\"{\\\"name\\\":\\\"Alice\\\",\\\"age\\\":30,\\\"isActive\\\":true}\"<\/span>;\n<span class=\"hljs-keyword\">var<\/span> jsonBytes = Encoding.UTF8.GetBytes(json);\n\n<span class=\"hljs-keyword\">var<\/span> reader = <span class=\"hljs-keyword\">new<\/span> Utf8JsonReader(jsonBytes);\n\n<span class=\"hljs-keyword\">while<\/span> (reader.Read())\n{\n    <span class=\"hljs-keyword\">if<\/span> (reader.TokenType == JsonTokenType.PropertyName)\n    {\n        string propertyName = reader.GetString();\n        reader.Read(); <span class=\"hljs-comment\">\/\/ Move to the value<\/span>\n\n        <span class=\"hljs-keyword\">switch<\/span> (propertyName)\n        {\n            <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-string\">\"name\"<\/span>:\n                string name = reader.GetString();\n                Console.WriteLine($<span class=\"hljs-string\">\"Name: {name}\"<\/span>);\n                <span class=\"hljs-keyword\">break<\/span>;\n            <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-string\">\"age\"<\/span>:\n                int age = reader.GetInt32();\n                Console.WriteLine($<span class=\"hljs-string\">\"Age: {age}\"<\/span>);\n                <span class=\"hljs-keyword\">break<\/span>;\n            <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-string\">\"isActive\"<\/span>:\n                bool isActive = reader.GetBoolean();\n                Console.WriteLine($<span class=\"hljs-string\">\"Active: {isActive}\"<\/span>);\n                <span class=\"hljs-keyword\">break<\/span>;\n        }\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Token Types<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Utf8JsonReader<\/code> exposes many token types:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>StartObject<\/code>, <code>EndObject<\/code><\/li>\n\n\n\n<li><code>StartArray<\/code>, <code>EndArray<\/code><\/li>\n\n\n\n<li><code>PropertyName<\/code><\/li>\n\n\n\n<li><code>String<\/code>, <code>Number<\/code>, <code>Boolean<\/code>, <code>Null<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You must carefully manage state as you read\u2014there\u2019s no &#8220;back&#8221; button. Think of it like a JSON cursor that always moves forward.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Advantages<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Minimal allocations<\/li>\n\n\n\n<li>Fast, especially for large payloads<\/li>\n\n\n\n<li>Full control over structure and validation<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">6. Implementing Custom Serialization Logic<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now that you\u2019ve got a handle on <code>Utf8JsonWriter<\/code>, it\u2019s time to go beyond basic examples and look at how to serialize more complex objects manually. Custom serialization is particularly useful when you need to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rename or omit certain fields<\/li>\n\n\n\n<li>Reorder properties for readability or compatibility<\/li>\n\n\n\n<li>Handle polymorphic data<\/li>\n\n\n\n<li>Serialize non-standard types (like <code>DateTimeOffset<\/code>, enums as strings, etc.)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s walk through a real-world scenario.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example Model<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose we have a class like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">public <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Product<\/span>\n<\/span>{\n    public int Id { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    public string Name { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    public decimal Price { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    public string? Description { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n    public List&lt;string&gt; Tags { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; } = new();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Custom Serialization Function<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s how you could write a method to serialize this manually using <code>Utf8JsonWriter<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> void WriteProduct(Utf8JsonWriter writer, Product product)\n{\n    writer.WriteStartObject();\n\n    writer.WriteNumber(<span class=\"hljs-string\">\"id\"<\/span>, product.Id);\n    writer.WriteString(<span class=\"hljs-string\">\"name\"<\/span>, product.Name);\n    writer.WriteNumber(<span class=\"hljs-string\">\"price\"<\/span>, product.Price);\n\n    <span class=\"hljs-keyword\">if<\/span> (!string.IsNullOrWhiteSpace(product.Description))\n    {\n        writer.WriteString(<span class=\"hljs-string\">\"description\"<\/span>, product.Description);\n    }\n\n    writer.WriteStartArray(<span class=\"hljs-string\">\"tags\"<\/span>);\n    <span class=\"hljs-keyword\">foreach<\/span> (<span class=\"hljs-keyword\">var<\/span> tag in product.Tags)\n    {\n        writer.WriteStringValue(tag);\n    }\n    writer.WriteEndArray();\n\n    writer.WriteEndObject();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Customizing Output<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">With manual control, you can choose:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>To omit null or empty properties (<code>Description<\/code> in this case)<\/li>\n\n\n\n<li>To write arrays even when they\u2019re empty, or skip them entirely<\/li>\n\n\n\n<li>To include metadata like timestamps or version fields dynamically<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Want to serialize enums as strings instead of numbers? Easy:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">writer<\/span><span class=\"hljs-selector-class\">.WriteString<\/span>(\"<span class=\"hljs-selector-tag\">status<\/span>\", <span class=\"hljs-selector-tag\">product<\/span><span class=\"hljs-selector-class\">.Status<\/span><span class=\"hljs-selector-class\">.ToString<\/span>());\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You can even nest objects:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">writer<\/span><span class=\"hljs-selector-class\">.WriteStartObject<\/span>(\"<span class=\"hljs-selector-tag\">manufacturer<\/span>\");\n<span class=\"hljs-selector-tag\">writer<\/span><span class=\"hljs-selector-class\">.WriteString<\/span>(\"<span class=\"hljs-selector-tag\">name<\/span>\", <span class=\"hljs-selector-tag\">product<\/span><span class=\"hljs-selector-class\">.Manufacturer<\/span><span class=\"hljs-selector-class\">.Name<\/span>);\n<span class=\"hljs-selector-tag\">writer<\/span><span class=\"hljs-selector-class\">.WriteString<\/span>(\"<span class=\"hljs-selector-tag\">country<\/span>\", <span class=\"hljs-selector-tag\">product<\/span><span class=\"hljs-selector-class\">.Manufacturer<\/span><span class=\"hljs-selector-class\">.Country<\/span>);\n<span class=\"hljs-selector-tag\">writer<\/span><span class=\"hljs-selector-class\">.WriteEndObject<\/span>();\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Formatting Tips<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You can optionally configure the writer for indentation if you want human-readable output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">var<\/span> options = <span class=\"hljs-keyword\">new<\/span> JsonWriterOptions\n{\n    Indented = <span class=\"hljs-literal\">true<\/span>\n};\n<span class=\"hljs-keyword\">var<\/span> writer = <span class=\"hljs-keyword\">new<\/span> Utf8JsonWriter(stream, options);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Why This Matters<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Manual serialization allows you to meet third-party API contracts that don&#8217;t align with your model, reduce payload size by excluding default or redundant values, and ensure your output is exactly what your system or client expects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Implementing Custom Deserialization Logic<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">While writing JSON manually gives you control over output, custom deserialization is where things really get interesting\u2014and occasionally tricky. With <code>Utf8JsonReader<\/code>, you handle incoming JSON token by token, building objects from the ground up. This is powerful when dealing with irregular schemas, partial updates, or performance-critical workloads where object instantiation needs to be lean and precise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s look at how to deserialize the <code>Product<\/code> class we used earlier.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Sample JSON<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json\">{\n  <span class=\"hljs-attr\">\"id\"<\/span>: <span class=\"hljs-number\">101<\/span>,\n  <span class=\"hljs-attr\">\"name\"<\/span>: <span class=\"hljs-string\">\"Laptop\"<\/span>,\n  <span class=\"hljs-attr\">\"price\"<\/span>: <span class=\"hljs-number\">1299.99<\/span>,\n  <span class=\"hljs-attr\">\"description\"<\/span>: <span class=\"hljs-string\">\"A high-end ultrabook\"<\/span>,\n  <span class=\"hljs-attr\">\"tags\"<\/span>: &#91;<span class=\"hljs-string\">\"electronics\"<\/span>, <span class=\"hljs-string\">\"portable\"<\/span>]\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Custom Deserialization Method<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> Product ReadProduct(ref Utf8JsonReader reader)\n{\n    <span class=\"hljs-keyword\">var<\/span> product = <span class=\"hljs-keyword\">new<\/span> Product();\n\n    <span class=\"hljs-keyword\">if<\/span> (reader.TokenType != JsonTokenType.StartObject)\n        <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> JsonException(<span class=\"hljs-string\">\"Expected StartObject token\"<\/span>);\n\n    <span class=\"hljs-keyword\">while<\/span> (reader.Read())\n    {\n        <span class=\"hljs-keyword\">if<\/span> (reader.TokenType == JsonTokenType.EndObject)\n            <span class=\"hljs-keyword\">return<\/span> product;\n\n        <span class=\"hljs-keyword\">if<\/span> (reader.TokenType == JsonTokenType.PropertyName)\n        {\n            string propertyName = reader.GetString();\n            reader.Read(); <span class=\"hljs-comment\">\/\/ Move to value<\/span>\n\n            <span class=\"hljs-keyword\">switch<\/span> (propertyName)\n            {\n                <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-string\">\"id\"<\/span>:\n                    product.Id = reader.GetInt32();\n                    <span class=\"hljs-keyword\">break<\/span>;\n                <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-string\">\"name\"<\/span>:\n                    product.Name = reader.GetString() ?? <span class=\"hljs-string\">\"\"<\/span>;\n                    <span class=\"hljs-keyword\">break<\/span>;\n                <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-string\">\"price\"<\/span>:\n                    product.Price = reader.GetDecimal();\n                    <span class=\"hljs-keyword\">break<\/span>;\n                <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-string\">\"description\"<\/span>:\n                    product.Description = reader.TokenType == JsonTokenType.<span class=\"hljs-keyword\">Null<\/span> ? <span class=\"hljs-keyword\">null<\/span> : reader.GetString();\n                    <span class=\"hljs-keyword\">break<\/span>;\n                <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-string\">\"tags\"<\/span>:\n                    <span class=\"hljs-keyword\">if<\/span> (reader.TokenType == JsonTokenType.StartArray)\n                    {\n                        <span class=\"hljs-keyword\">while<\/span> (reader.Read() &amp;&amp; reader.TokenType != JsonTokenType.EndArray)\n                        {\n                            product.Tags.Add(reader.GetString() ?? <span class=\"hljs-string\">\"\"<\/span>);\n                        }\n                    }\n                    <span class=\"hljs-keyword\">break<\/span>;\n                <span class=\"hljs-keyword\">default<\/span>:\n                    reader.Skip(); <span class=\"hljs-comment\">\/\/ Safely ignore unknown fields<\/span>\n                    <span class=\"hljs-keyword\">break<\/span>;\n            }\n        }\n    }\n\n    <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> JsonException(<span class=\"hljs-string\">\"Incomplete JSON object\"<\/span>);\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Key Concepts<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Ref Parameter<\/strong>: The reader must be passed by reference (<code>ref Utf8JsonReader<\/code>) because it\u2019s a struct.<\/li>\n\n\n\n<li><strong>Validation<\/strong>: You\u2019re responsible for checking token types to ensure the JSON structure is valid.<\/li>\n\n\n\n<li><strong>Fallbacks<\/strong>: If a value is missing or null, provide sensible defaults.<\/li>\n\n\n\n<li><strong>Skipping Unknowns<\/strong>: Use <code>reader.Skip()<\/code> to move past unexpected properties gracefully.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Benefits of Custom Deserialization<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You can handle flexible or evolving JSON formats without breaking<\/li>\n\n\n\n<li>You can selectively read only relevant fields, reducing overhead<\/li>\n\n\n\n<li>You can layer validation or transformation into the parsing logic<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This is especially useful when consuming third-party APIs where field names may differ, optional properties may appear inconsistently, or nested structures require conditional logic.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">8. Putting It All Together: Full Serialization\/Deserialization Example<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now that you\u2019ve learned how to manually write and read JSON using <code>Utf8JsonWriter<\/code> and <code>Utf8JsonReader<\/code>, let\u2019s walk through a complete example to reinforce everything.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We\u2019ll use the <code>Product<\/code> class again, perform both serialization and deserialization, and show how the two processes work seamlessly together.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Full Round-Trip Example<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">using System;\nusing System.IO;\nusing System.Text;\nusing System.Text.Json;\nusing System.Collections.Generic;\n\n<span class=\"hljs-comment\">\/\/ Product class defined earlier...<\/span>\n\n<span class=\"hljs-comment\">\/\/ Serialize<\/span>\n<span class=\"hljs-keyword\">var<\/span> product = <span class=\"hljs-keyword\">new<\/span> Product\n{\n    Id = <span class=\"hljs-number\">42<\/span>,\n    Name = <span class=\"hljs-string\">\"Mechanical Keyboard\"<\/span>,\n    Price = <span class=\"hljs-number\">109.95<\/span>m,\n    Description = <span class=\"hljs-string\">\"RGB backlit with hot-swappable switches\"<\/span>,\n    Tags = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-keyword\">List<\/span>&lt;string&gt; { <span class=\"hljs-string\">\"electronics\"<\/span>, <span class=\"hljs-string\">\"input-device\"<\/span> }\n};\n\nusing <span class=\"hljs-keyword\">var<\/span> stream = <span class=\"hljs-keyword\">new<\/span> MemoryStream();\n<span class=\"hljs-keyword\">var<\/span> writer = <span class=\"hljs-keyword\">new<\/span> Utf8JsonWriter(stream, <span class=\"hljs-keyword\">new<\/span> JsonWriterOptions { Indented = <span class=\"hljs-keyword\">true<\/span> });\nWriteProduct(writer, product);\nwriter.Flush();\n\nstring json = Encoding.UTF8.GetString(stream.ToArray());\nConsole.WriteLine(<span class=\"hljs-string\">\"Serialized JSON:\"<\/span>);\nConsole.WriteLine(json);\n\n<span class=\"hljs-comment\">\/\/ Deserialize<\/span>\n<span class=\"hljs-keyword\">var<\/span> jsonBytes = Encoding.UTF8.GetBytes(json);\n<span class=\"hljs-keyword\">var<\/span> reader = <span class=\"hljs-keyword\">new<\/span> Utf8JsonReader(jsonBytes);\nProduct parsedProduct = ReadProduct(ref reader);\n\nConsole.WriteLine(<span class=\"hljs-string\">\"\\nDeserialized Product:\"<\/span>);\nConsole.WriteLine($<span class=\"hljs-string\">\"ID: {parsedProduct.Id}\"<\/span>);\nConsole.WriteLine($<span class=\"hljs-string\">\"Name: {parsedProduct.Name}\"<\/span>);\nConsole.WriteLine($<span class=\"hljs-string\">\"Price: {parsedProduct.Price:C}\"<\/span>);\nConsole.WriteLine($<span class=\"hljs-string\">\"Tags: {string.Join(\"<\/span>, <span class=\"hljs-string\">\", parsedProduct.Tags)}\"<\/span>);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Why This Matters<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This round-trip shows how you can:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fully control what gets serialized and how it\u2019s formatted<\/li>\n\n\n\n<li>Build an object safely and predictably from incoming JSON<\/li>\n\n\n\n<li>Avoid unnecessary overhead from reflection or third-party libraries<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This approach is perfect for performance-critical systems, custom APIs, or interoperable services with strict formatting needs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">9. Error Handling and Edge Cases<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When working with JSON manually, you need to account for the messiness of real-world data. Unlike <code>JsonSerializer<\/code>, which throws structured exceptions, <code>Utf8JsonReader<\/code> and <code>Utf8JsonWriter<\/code> leave error handling up to you. That\u2019s both a responsibility and a benefit\u2014you get to decide how strict or flexible your logic should be.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common Pitfalls<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Unexpected Token Types<\/strong>: Always check <code>TokenType<\/code> before calling <code>GetString()<\/code>, <code>GetInt32()<\/code>, etc. Accessing the wrong method will throw an exception.<\/li>\n\n\n\n<li><strong>Missing or Extra Fields<\/strong>: If a required property is missing, decide whether to use a default, throw an error, or log and continue.<\/li>\n\n\n\n<li><strong>Null Values<\/strong>: Handle <code>JsonTokenType.Null<\/code> explicitly when reading strings or nested objects.<\/li>\n\n\n\n<li><strong>Malformed JSON<\/strong>: Wrap deserialization in a try-catch block to detect corruption or incomplete input.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Defensive Patterns<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">if<\/span> (!reader.TryGetInt32(out int value))\n{\n    <span class=\"hljs-comment\">\/\/ fallback or log<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Being cautious in your parsing logic ensures your application won\u2019t crash on malformed data or future changes to JSON shape.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">10. Performance Considerations<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One of the key reasons to use <code>Utf8JsonWriter<\/code> and <code>Utf8JsonReader<\/code> is performance. Compared to high-level serializers like <code>JsonSerializer<\/code>, these low-level APIs offer:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Fewer allocations<\/strong>: No boxing, reflection, or object instantiation unless you explicitly choose to.<\/li>\n\n\n\n<li><strong>Stream-based processing<\/strong>: Ideal for large payloads or streaming scenarios.<\/li>\n\n\n\n<li><strong>Precise control<\/strong>: Read only the data you need; skip the rest.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In benchmarks, manual JSON parsing using these APIs often outperforms traditional serializers\u2014especially when you&#8217;re dealing with large volumes of data, partial updates, or constrained environments like microservices.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, with great power comes great responsibility. You trade off convenience and readability for control and speed. That makes these APIs better suited for hot paths (e.g. request\/response processing, logging pipelines) rather than general-purpose data handling.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pro Tip<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To further reduce overhead, reuse buffers and streams when possible, and avoid unnecessary conversions (like UTF-16 string decoding) unless needed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is <strong>Section 11: Conclusion and Next Steps (\u2248100 words)<\/strong>:<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">11. Conclusion and Next Steps<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You\u2019ve now seen how <code>Utf8JsonWriter<\/code> and <code>Utf8JsonReader<\/code> give you full control over JSON serialization and deserialization in .NET. From writing primitive values to handling complex object graphs and navigating JSON token streams, you\u2019ve learned how to bypass the limitations of automatic serialization with a more hands-on, performant approach.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These tools are perfect for high-throughput APIs, custom integrations, and scenarios where efficiency and structure control are critical.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. Introduction to JSON Serialization in .NET JSON has become the lingua franca of modern software systems. Whether you&#8217;re building APIs, consuming web services, or storing configuration data, chances are you&#8217;re dealing with JSON. In the .NET ecosystem, handling JSON has become increasingly streamlined\u2014thanks to the evolution of System.Text.Json, which provides a high-performance, low-allocation alternative [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[8,4],"tags":[],"class_list":["post-2245","post","type-post","status-publish","format-standard","category-csharp","category-programming-languages","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Utf8JsonWriter and Utf8JsonReader Tutorial for Custom JSON Serialization in C#<\/title>\n<meta name=\"description\" content=\"Full guide to Utf8JsonWriter and Utf8JsonReader\u2014create custom JSON logic in .NET with full control and better speed.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Utf8JsonWriter and Utf8JsonReader Tutorial for Custom JSON Serialization in C#\" \/>\n<meta property=\"og:description\" content=\"Full guide to Utf8JsonWriter and Utf8JsonReader\u2014create custom JSON logic in .NET with full control and better speed.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/\" \/>\n<meta property=\"article:published_time\" content=\"2025-04-30T18:08:51+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-30T18:08:55+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"Building Custom JSON Serialization Logic Using Utf8JsonWriter and Utf8JsonReader\",\"datePublished\":\"2025-04-30T18:08:51+00:00\",\"dateModified\":\"2025-04-30T18:08:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\\\/\"},\"wordCount\":1820,\"articleSection\":[\"C#\",\"Programming Languages\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\\\/\",\"name\":\"Utf8JsonWriter and Utf8JsonReader Tutorial for Custom JSON Serialization in C#\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2025-04-30T18:08:51+00:00\",\"dateModified\":\"2025-04-30T18:08:55+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"Full guide to Utf8JsonWriter and Utf8JsonReader\u2014create custom JSON logic in .NET with full control and better speed.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Building Custom JSON Serialization Logic Using Utf8JsonWriter and Utf8JsonReader\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Utf8JsonWriter and Utf8JsonReader Tutorial for Custom JSON Serialization in C#","description":"Full guide to Utf8JsonWriter and Utf8JsonReader\u2014create custom JSON logic in .NET with full control and better speed.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/","og_locale":"en_US","og_type":"article","og_title":"Utf8JsonWriter and Utf8JsonReader Tutorial for Custom JSON Serialization in C#","og_description":"Full guide to Utf8JsonWriter and Utf8JsonReader\u2014create custom JSON logic in .NET with full control and better speed.","og_url":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/","article_published_time":"2025-04-30T18:08:51+00:00","article_modified_time":"2025-04-30T18:08:55+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"Building Custom JSON Serialization Logic Using Utf8JsonWriter and Utf8JsonReader","datePublished":"2025-04-30T18:08:51+00:00","dateModified":"2025-04-30T18:08:55+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/"},"wordCount":1820,"articleSection":["C#","Programming Languages"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/","url":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/","name":"Utf8JsonWriter and Utf8JsonReader Tutorial for Custom JSON Serialization in C#","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2025-04-30T18:08:51+00:00","dateModified":"2025-04-30T18:08:55+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"Full guide to Utf8JsonWriter and Utf8JsonReader\u2014create custom JSON logic in .NET with full control and better speed.","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/building-custom-json-serialization-logic-using-utf8jsonwriter-and-utf8jsonreader\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"Building Custom JSON Serialization Logic Using Utf8JsonWriter and Utf8JsonReader"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/2245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=2245"}],"version-history":[{"count":3,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/2245\/revisions"}],"predecessor-version":[{"id":2248,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/2245\/revisions\/2248"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=2245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=2245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=2245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}