This breaks API requests where slashes or dots appear in path parameters. Such requests
arise, for example, when these characters appear in the name of a GCS object.
== Problem 2: Fewer unreserved characters
Unless IDN/IRI parsing is enabled -- which it is not, by default, prior to .NET 4.5 --
Uri.EscapeDataString uses the set of "unreserved" characters from RFC 2396 instead of the
newer,smallerlist from RFC 3986. We build requests using URI templating as described
by RFC 6570, which specifies that the latter definition (RFC 3986) should be used.
This breaks API requests with parameters including any of: !*'()
== Solutions
Though the default behaviors changed in .NET 4.5, these "quirks" remain for compatibility
unless the application explicitly targets the new runtime. Usually, that means adding a
TargetFrameworkAttribute to the entry assembly.
Applications running on .NET 4.0 or later can also set "DontUnescapePathDotsAndSlashes"
and enable IDN/IRI parsing using app.config or web.config.
As a class library, we can't control app.config or the entry assembly, so we can't take
either approach. Instead, we resort to reflection trickery to try to solve these problems
if we detect they exist. Sorry.
Methods
PatchUriQuirks()
public static void PatchUriQuirks()
Patch URI quirks in System.Uri. See class summary for details.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-04 UTC."],[[["\u003cp\u003e\u003ccode\u003eUriPatcher\u003c/code\u003e is a static class in the \u003ccode\u003eGoogle.Apis.Util\u003c/code\u003e namespace designed to address specific issues within the .NET Framework's \u003ccode\u003eSystem.Uri\u003c/code\u003e implementation.\u003c/p\u003e\n"],["\u003cp\u003eIt primarily deals with two problems: the incorrect unescaping of slashes and dots in URLs before .NET 4.5 and the use of an outdated set of unreserved characters for data escaping.\u003c/p\u003e\n"],["\u003cp\u003eThe class implements workarounds using reflection to handle these quirks because it cannot control application configurations, which would otherwise resolve the issues in .NET 4.5 and later versions.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003ePatchUriQuirks()\u003c/code\u003e method is available to apply these fixes to the \u003ccode\u003eSystem.Uri\u003c/code\u003e class when the described issues are detected.\u003c/p\u003e\n"],["\u003cp\u003eIt is available in multiple versions from 1.50.0 all the way to the latest version of 1.69.0.\u003c/p\u003e\n"]]],[],null,["# Class UriPatcher (1.69.0)\n\nVersion latestkeyboard_arrow_down\n\n- [1.69.0 (latest)](/dotnet/docs/reference/Google.Apis/latest/Google.Apis.Util.UriPatcher)\n- [1.68.0](/dotnet/docs/reference/Google.Apis/1.68.0/Google.Apis.Util.UriPatcher)\n- [1.60.0](/dotnet/docs/reference/Google.Apis/1.60.0/Google.Apis.Util.UriPatcher)\n- [1.59.0](/dotnet/docs/reference/Google.Apis/1.59.0/Google.Apis.Util.UriPatcher)\n- [1.55.0](/dotnet/docs/reference/Google.Apis/1.55.0/Google.Apis.Util.UriPatcher)\n- [1.50.0](/dotnet/docs/reference/Google.Apis/1.50.0/Google.Apis.Util.UriPatcher) \n\n public static class UriPatcher\n\nWorkarounds for some unfortunate behaviors in the .NET Framework's\nimplementation of System.Uri \n\nInheritance\n-----------\n\n[object](https://learn.microsoft.com/dotnet/api/system.object) \\\u003e UriPatcher \n\nInherited Members\n-----------------\n\n[object.Equals(object)](https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)) \n[object.Equals(object, object)](https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)) \n[object.GetHashCode()](https://learn.microsoft.com/dotnet/api/system.object.gethashcode) \n[object.GetType()](https://learn.microsoft.com/dotnet/api/system.object.gettype) \n[object.MemberwiseClone()](https://learn.microsoft.com/dotnet/api/system.object.memberwiseclone) \n[object.ReferenceEquals(object, object)](https://learn.microsoft.com/dotnet/api/system.object.referenceequals) \n[object.ToString()](https://learn.microsoft.com/dotnet/api/system.object.tostring)\n\nNamespace\n---------\n\n[Google.Apis.Util](/dotnet/docs/reference/Google.Apis/latest/Google.Apis.Util)\n\nAssembly\n--------\n\nGoogle.Apis.Core.dll\n\nRemarks\n-------\n\nUriPatcher lets us work around some unfortunate behaviors in the .NET Framework's\nimplementation of System.Uri.\n\n== Problem 1: Slashes and dots\n\nPrior to .NET 4.5, System.Uri would always unescape \"%2f\" (\"/\") and \"%5c\" (\"\\\\\").\nRelative path components were also compressed.\n\nAs a result, this: \"\u003chttp://www.example.com/.%2f.%5c./\u003e\"\n... turned into this: \"\u003chttp://www.example.com/\u003e\"\n\nThis breaks API requests where slashes or dots appear in path parameters. Such requests\narise, for example, when these characters appear in the name of a GCS object.\n\n== Problem 2: Fewer unreserved characters\n\nUnless IDN/IRI parsing is enabled -- which it is not, by default, prior to .NET 4.5 --\nUri.EscapeDataString uses the set of \"unreserved\" characters from RFC 2396 instead of the\nnewer, *smaller* list from RFC 3986. We build requests using URI templating as described\nby RFC 6570, which specifies that the latter definition (RFC 3986) should be used.\n\nThis breaks API requests with parameters including any of: !\\*'()\n\n== Solutions\n\nThough the default behaviors changed in .NET 4.5, these \"quirks\" remain for compatibility\nunless the application explicitly targets the new runtime. Usually, that means adding a\nTargetFrameworkAttribute to the entry assembly.\n\nApplications running on .NET 4.0 or later can also set \"DontUnescapePathDotsAndSlashes\"\nand enable IDN/IRI parsing using app.config or web.config.\n\nAs a class library, we can't control app.config or the entry assembly, so we can't take\neither approach. Instead, we resort to reflection trickery to try to solve these problems\nif we detect they exist. Sorry.\n\nMethods\n-------\n\n### PatchUriQuirks()\n\n public static void PatchUriQuirks()\n\nPatch URI quirks in System.Uri. See class summary for details."]]