Skip to content

Conversation

@StephenMolloy
Copy link
Member

Backport of #119835 to release/10.0-rc2

/cc @StephenMolloy

Customer Impact

  • Customer reported
  • Found internally

This has been a customer ask for a while – This PR introduces first-class (primitive) serializer support for DateOnly and TimeOnly in XmlSerializer and DataContractSerializer, closing a gap as these types see growing real-world adoption—especially via EF scaffolding and modern data models that already emit them. Treating them as primitives with strict, canonical ISO wire forms and restricted XSD simple types prevents silent data loss (e.g., from offset-bearing times) and enables clean schema export/import parity with existing primitives. The approach extends primitive registration tables, adds focused parse/format delegates, and offers an attribute-based escape hatch for legacy xs:time interop while remaining purely additive and backward compatible.

Regression

  • Yes
  • No

Not a regression. DateOnly and TimeOnly were not .Net data types when our serializers were originally designed.

Testing

Many tests are included with the PR.

Risk

Low. The change is additive (introducing new primitive serializers without altering existing DateTime/DateTimeOffset behavior), uses well‑bounded canonical text formats, guards against data loss via restrictive XSD pattern facets, and is backed by comprehensive round‑trip, schema export/import, override, and backward‑compat tests—so remaining exposure is limited mainly to unforeseen edge cases in newly added parsing/formatting paths.

IMPORTANT: If this backport is for a servicing release, please verify that:

  • The PR target branch is release/X.0-staging, not release/X.0.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

Copilot AI review requested due to automatic review settings September 23, 2025 17:54
@StephenMolloy StephenMolloy self-assigned this Sep 23, 2025
@StephenMolloy StephenMolloy added Servicing-consider Issue for next servicing release review area-Serialization labels Sep 23, 2025
@StephenMolloy StephenMolloy added this to the 10.0.0 milestone Sep 23, 2025
Copy link
Contributor

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 introduces first-class primitive serialization support for DateOnly and TimeOnly in both XmlSerializer and DataContractSerializer. The change adds comprehensive serialization capabilities for these .NET 6+ types, treating them as primitive types similar to DateTime and DateTimeOffset, with strict canonical wire formats to prevent data loss.

Key Changes:

  • Adds primitive serializer support for DateOnly and TimeOnly types in both XmlSerializer and DataContractSerializer
  • Implements restricted XSD schema types with pattern facets for validation
  • Provides backward compatibility through an attribute-based escape hatch for legacy xs:time interop

Reviewed Changes

Copilot reviewed 29 out of 30 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
System.Xml.XmlSerializer/ref/System.Xml.XmlSerializer.cs Adds reference API surface for DateOnly/TimeOnly conversion methods
XsdDataContractExporterTests/SchemaUtils.cs Updates schema dumping utility to optionally include serialization namespace
XsdDataContractExporterTests/ExporterTypesTests.cs Updates test expectations for new primitive types and adds DateOnly/TimeOnly schema export tests
XsdDataContractExporterTests/ExporterApiTests.cs Updates global type counts to account for new primitive types
SerializationTypes.cs Adds test types containing DateOnly/TimeOnly properties with various attributes
SerializationTestTypes/Primitives.cs Adds DateTimeOnlyWrapper class for DataContractSerializer tests
DataContractSerializer.cs Adds comprehensive tests for DateOnly/TimeOnly serialization including binary format
DataContractJsonSerializer.cs Adds JSON serialization tests for DateOnly/TimeOnly
ImporterTests.cs Adds schema import tests verifying DateOnly/TimeOnly type mapping
XmlSerializerTests.cs Extensive test coverage for DateOnly/TimeOnly serialization, parsing, and compatibility
XmlSerializerTests.RuntimeOnly.cs Schema import/export tests and removes some redundant test code
Core serialization files Implements the actual serialization logic for DateOnly/TimeOnly across the XML serialization stack

Copy link
Member

@Youssef1313 Youssef1313 left a comment

Choose a reason for hiding this comment

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

In MSTest we have special handling for DateOnly/TimeOnly in https://github.com/microsoft/testfx/blob/0f88daa1f377afaac08ffff1c29ecca6cb79e9a4/src/Adapter/MSTestAdapter.PlatformServices/Helpers/DataSerializationHelper.cs

I assume that special handling will no longer be needed in .NET 10?

@artl93 artl93 added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Sep 24, 2025
@artl93 artl93 merged commit 70801b2 into dotnet:release/10.0-rc2 Sep 24, 2025
92 of 93 checks passed
@StephenMolloy
Copy link
Member Author

In MSTest we have special handling for DateOnly/TimeOnly in https://github.com/microsoft/testfx/blob/0f88daa1f377afaac08ffff1c29ecca6cb79e9a4/src/Adapter/MSTestAdapter.PlatformServices/Helpers/DataSerializationHelper.cs

I assume that special handling will no longer be needed in .NET 10?

Correct. Special handling should no longer be needed. However, you can continue to use your surrogate classes if you want. I would note that your surrogates are writing out to xml what appears to be the underlying data for each type (day number/ticks) whereas the new in-box handling of these types adheres to a restricted format of the XML date and time types, which is a string representation. So whichever method you choose for serializing DateOnly/TimeOnly, you'll need to be consistent on both serialization and deserialization.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-Serialization Servicing-approved Approved for servicing release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants