Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Oct 20, 2025

  • Review the current nullable-annotations.md documentation
  • Understand the difference between missing/undefined values and null values in JSON deserialization
  • Add a new section explaining that missing (undefined) JSON values are treated differently from null values
  • Create code examples demonstrating the behavior with missing values vs null values
  • Update the snippets to include examples showing missing values
  • Build and validate the code snippets compile correctly
  • Review and ensure the documentation follows writing style guidelines
  • Address reviewer feedback about missing properties being left at default values rather than set to null
  • Final verification of all changes
Original prompt

This section details on the original issue you should resolve

<issue_title>Deserialization with RespectNullableAnnotations = true does not treat undefined as null</issue_title>
<issue_description>### Type of issue

Missing information

Description

JavaScript distinguishes between null and undefined and when JSON is deserialized a missing value becomes undefined. However, undefined does not exist in .NET and a missing string or object value deserializes to .NET null. This can lead to confusion when setting RespectNullableAnnotations to true because if the JSON value is missing, no exception is thrown when the target property is non-nullable leading to the property being null despite the setting. I think this article could be improved by explaining this.

Even better, it would be nice if JSON deserialization could be configured to treat a missing value the same way as null when deserializing to a non-null string or object. 🙏 Yes, I know this is not a documentation issue, but I had to mention it. 😀

Page URL

https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/nullable-annotations

Content source URL

https://github.com/dotnet/docs/blob/main/docs/standard/serialization/system-text-json/nullable-annotations.md

Document Version Independent Id

7ae3d826-764a-2c29-a251-1a237beedd1a

Platform Id

5aacc351-ddac-0ce8-57df-aabac452d55b

Article author

@gewarren

Metadata

  • ID: 44d16e49-e10a-92b0-147e-a46542aefd51
  • PlatformId: 5aacc351-ddac-0ce8-57df-aabac452d55b
  • Service: dotnet-fundamentals

Related Issues</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #49298


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.


Internal previews

📄 File 🔗 Preview link
docs/standard/serialization/system-text-json/nullable-annotations.md docs/standard/serialization/system-text-json/nullable-annotations

@Copilot Copilot AI changed the title [WIP] Fix deserialization behavior for undefined values Document missing vs. null value behavior in RespectNullableAnnotations Oct 20, 2025
@Copilot Copilot AI requested a review from gewarren October 20, 2025 22:20
Copilot finished work on behalf of gewarren October 20, 2025 22:20
Copy link
Contributor

@gewarren gewarren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified the code works as advertised.

Removed example demonstrating exception on explicit null value during deserialization.
@gewarren gewarren marked this pull request as ready for review October 20, 2025 23:39
@gewarren gewarren requested a review from a team as a code owner October 20, 2025 23:39
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR addresses a documentation gap by clarifying how RespectNullableAnnotations behaves differently when JSON properties are missing versus explicitly set to null. The documentation update explains that JavaScript's undefined (missing property) and null (explicit null value) both deserialize to .NET null, but only explicit null values trigger exceptions for non-nullable properties.

Key Changes:

  • Added a new "Missing values versus null values" section explaining the behavioral distinction
  • Created a code example demonstrating that missing properties don't throw exceptions
  • Updated metadata (date and added ai-usage frontmatter)

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
nullable-annotations.md Added new section documenting missing vs. null value behavior and enforcement guidance
Nullable.cs Added Nullable4 class with MissingVsNull example demonstrating missing property behavior
Program.cs Updated to run the new Nullable4 example


## Missing values versus null values

It's important to understand the distinction between *missing JSON properties* and *properties with explicit `null` values* when you set <xref:System.Text.Json.JsonSerializerOptions.RespectNullableAnnotations>. JavaScript distinguishes between `undefined` (missing property) and `null` (explicit null value). However, .NET doesn't have an `undefined` concept, so both cases deserialize to `null` in .NET.
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cross-reference tag should use the property name format RespectNullableAnnotations instead of the full type path. Change <xref:System.Text.Json.JsonSerializerOptions.RespectNullableAnnotations> to just reference the property consistently with how it's used elsewhere in the document (as RespectNullableAnnotations).

Suggested change
It's important to understand the distinction between *missing JSON properties* and *properties with explicit `null` values* when you set <xref:System.Text.Json.JsonSerializerOptions.RespectNullableAnnotations>. JavaScript distinguishes between `undefined` (missing property) and `null` (explicit null value). However, .NET doesn't have an `undefined` concept, so both cases deserialize to `null` in .NET.
It's important to understand the distinction between *missing JSON properties* and *properties with explicit `null` values* when you set <xref:RespectNullableAnnotations>. JavaScript distinguishes between `undefined` (missing property) and `null` (explicit null value). However, .NET doesn't have an `undefined` concept, so both cases deserialize to `null` in .NET.

Copilot uses AI. Check for mistakes.

During deserialization, when `RespectNullableAnnotations` is `true`:

- An **explicit null value** throws an exception for non-nullable properties. For example, `{"Name":null}` throws an exception when deserializing to a non-nullable `string Name` property.
- A **missing property** doesn't throw an exception, even for non-nullable properties. For example, `{}` doesn't throw an exception when deserializing to a non-nullable `string Name` property. The property is set to `null`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot This is not entirely accurate. Missing properties mean that the serializer will not set the properties, leaving them at their default values as set by the constructor. This implies that a non-nullable string Name that is left uninitialized will give out a warning from the compiler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right. I've updated the documentation to clarify that the serializer doesn't set the property at all—it leaves it at its default value from the constructor. For uninitialized non-nullable reference types, this results in null and triggers a compiler warning. Fixed in commit e296c5a.

@Copilot Copilot AI requested a review from eiriktsarpalis October 21, 2025 06:15
Copilot finished work on behalf of eiriktsarpalis October 21, 2025 06:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deserialization with RespectNullableAnnotations = true does not treat undefined as null

3 participants