Skip to content

Commit 3b4ddd8

Browse files
authored
Add breaking change documentation for System.IO.Packaging case-insensitive URI comparison in .NET 8 (#48777)
1 parent 25623f6 commit 3b4ddd8

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

docs/core/compatibility/8.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ If you're migrating an app to .NET 8, the breaking changes listed here might aff
5757
| [ITypeDescriptorContext nullable annotations](core-libraries/8.0/itypedescriptorcontext-props.md) | Source incompatible |
5858
| [Legacy Console.ReadKey removed](core-libraries/8.0/console-readkey-legacy.md) | Behavioral change |
5959
| [Method builders generate parameters with HasDefaultValue set to false](core-libraries/8.0/parameterinfo-hasdefaultvalue.md) | Behavioral change |
60+
| [Package part URIs are now compared case-insensitively in System.IO.Packaging](core-libraries/8.0/system-io-packaging-case-insensitive-uri.md) | Behavioral change |
6061
| [ProcessStartInfo.WindowStyle honored when UseShellExecute is false](core-libraries/8.0/processstartinfo-windowstyle.md) | Behavioral change |
6162
| [RuntimeIdentifier returns platform for which runtime was built](core-libraries/8.0/runtimeidentifier.md) | Behavioral change |
6263
| [`Type.GetType` throws exception for all invalid element types](core-libraries/8.0/type-gettype.md) | Behavioral change |
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: "Breaking change: Package part URIs are now compared case-insensitively in System.IO.Packaging"
3+
description: "Learn about the breaking change in .NET 8 where System.IO.Packaging now compares package part URIs case-insensitively to align with the OPC specification."
4+
ms.date: 09/29/2024
5+
ai-usage: ai-generated
6+
ms.custom: https://github.com/dotnet/runtime/issues/112783
7+
---
8+
9+
# Package part URIs are now compared case-insensitively in System.IO.Packaging
10+
11+
Previously, part names and overrides that differed only by ASCII case (for example, `/part` vs `/PART`) were not considered equivalent in <xref:System.IO.Packaging>, even though the Open Packaging Conventions (OPC) specification requires case-insensitive equivalence (§7.2.3.5, ECMA-376). This change fixes the bug and brings .NET 5–9 in line with both .NET Framework and the OPC specification.
12+
13+
## Version introduced
14+
15+
.NET 8
16+
17+
## Previous behavior
18+
19+
URI comparisons were case-sensitive.
20+
Content type overrides failed if the casing differed between the part URI and the override entry.
21+
Some non-compliant packages containing duplicate entries differing only in case (for example, `/part` and `/PART`) could be loaded, leading to ambiguous results.
22+
23+
## New behavior
24+
25+
URI comparisons are case-insensitive (<xref:System.StringComparison.OrdinalIgnoreCase?displayProperty=nameWithType>).
26+
Overrides with different casing now work as expected.
27+
Non-compliant packages containing multiple entries that differ only by case are now rejected when opened. This aligns with .NET Framework and the OPC specification.
28+
29+
## Type of breaking change
30+
31+
This is a [behavioral change](../../categories.md#behavioral-change).
32+
33+
## Reason for change
34+
35+
This change aligns <xref:System.IO.Packaging> behavior with:
36+
37+
- The OPC specification (case-insensitive URI equivalence is mandatory).
38+
- Existing .NET Framework behavior, which already enforces case-insensitive matching.
39+
40+
It prevents ambiguous lookups and ensures consistent results, and fixes [dotnet/runtime#112783](https://github.com/dotnet/runtime/issues/112783).
41+
42+
## Recommended action
43+
44+
Ensure that OPC packages do not contain part names differing only by case, as this is invalid per the OPC specification.
45+
46+
If consuming packages that violate the specification:
47+
48+
- Contact the package author to fix the package.
49+
- If you need to read or inspect the contents, you can open the package as a ZIP archive. Unlike the Package API, ZIP archives do not enforce OPC rules and will allow you to access all entries, including those with conflicting case names.
50+
51+
## Affected APIs
52+
53+
- <xref:System.IO.Packaging.Package.GetPart(System.Uri)?displayProperty=fullName>
54+
- <xref:System.IO.Packaging.Package.CreatePart(System.Uri,System.String)?displayProperty=fullName>

docs/core/compatibility/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ items:
398398
href: core-libraries/8.0/console-readkey-legacy.md
399399
- name: Method builders generate parameters with HasDefaultValue=false
400400
href: core-libraries/8.0/parameterinfo-hasdefaultvalue.md
401+
- name: Package part URIs are now compared case-insensitively in System.IO.Packaging
402+
href: core-libraries/8.0/system-io-packaging-case-insensitive-uri.md
401403
- name: ProcessStartInfo.WindowStyle honored when UseShellExecute is false
402404
href: core-libraries/8.0/processstartinfo-windowstyle.md
403405
- name: RuntimeIdentifier returns platform for which runtime was built

0 commit comments

Comments
 (0)