From 4f6c0b66c1652a9703924db76b08115d5bd23372 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 27 Apr 2026 17:07:54 -0400 Subject: [PATCH 1/3] fix: Honor EnumMember attribute in query-string serialization The query-string builder used Enum.ToString(), producing PascalCase values like "Desc" that the API rejects. It now reads [EnumMember(Value="...")] to emit the correct wire values ("desc", "asc"). Also makes ListOptions.Order nullable so callers can omit the parameter entirely instead of always sending a value. --- .../Client/Utilities/RequestUtilities.cs | 23 ++++++++++++++++++- .../_common/_interfaces/ListOptions.cs | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/WorkOS.net/Client/Utilities/RequestUtilities.cs b/src/WorkOS.net/Client/Utilities/RequestUtilities.cs index fc17b598..51fe2d91 100644 --- a/src/WorkOS.net/Client/Utilities/RequestUtilities.cs +++ b/src/WorkOS.net/Client/Utilities/RequestUtilities.cs @@ -12,6 +12,7 @@ namespace WorkOS using System.Net.Http; using System.Net.Http.Headers; using System.Reflection; + using System.Runtime.Serialization; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -353,7 +354,7 @@ private static void AddScalar(string key, object? value, List(key, rendered)); } + /// + /// Return the wire value for an enum member by reading its + /// . Falls back to + /// ToString() when the attribute is absent. + /// + private static string ResolveEnumWireValue(Enum value) + { + var member = value.GetType().GetField(value.ToString()); + if (member != null) + { + var attr = member.GetCustomAttribute(); + if (attr != null && attr.Value != null) + { + return attr.Value; + } + } + + return value.ToString(); + } + /// /// Contract resolver that includes internal properties so that /// service-injected fields (grant_type, client_id, client_secret) diff --git a/src/WorkOS.net/Services/_common/_interfaces/ListOptions.cs b/src/WorkOS.net/Services/_common/_interfaces/ListOptions.cs index ee488fd0..3c342454 100644 --- a/src/WorkOS.net/Services/_common/_interfaces/ListOptions.cs +++ b/src/WorkOS.net/Services/_common/_interfaces/ListOptions.cs @@ -35,6 +35,6 @@ public class ListOptions : BaseOptions /// [JsonProperty("order")] [STJS.JsonPropertyName("order")] - public PaginationOrder Order { get; set; } = PaginationOrder.Desc; + public PaginationOrder? Order { get; set; } } } From 77cf7d20e8ed8babfe939dc949f5b69f99c47913 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 27 Apr 2026 17:07:57 -0400 Subject: [PATCH 2/3] fix: Update NonGetQueryParamsTest for DeleteResource rename The test still referenced the old DeleteResourceByExternalId method signature, which was removed in 4ceb3de. Updated to use the current DeleteResource API so the test project compiles. --- .../Client/NonGetQueryParamsTest.cs | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/test/WorkOSTests/Client/NonGetQueryParamsTest.cs b/test/WorkOSTests/Client/NonGetQueryParamsTest.cs index f57f945c..d80024aa 100644 --- a/test/WorkOSTests/Client/NonGetQueryParamsTest.cs +++ b/test/WorkOSTests/Client/NonGetQueryParamsTest.cs @@ -27,15 +27,13 @@ public async Task DeleteWithBoolQueryParam_IncludesCascadeDeleteOnUri() httpMock.MockResponse( HttpMethod.Delete, - "/authorization/organizations/org_1/resources/file/ext_42", + "/authorization/resources/res_1", HttpStatusCode.NoContent, "{}"); - await client.Authorization.DeleteResourceByExternalId( - "org_1", - "file", - "ext_42", - new AuthorizationDeleteResourceByExternalIdOptions { CascadeDelete = true }); + await client.Authorization.DeleteResource( + "res_1", + new AuthorizationDeleteResourceOptions { CascadeDelete = true }); var last = Assert.Single(httpMock.CapturedRequests); Assert.Equal(HttpMethod.Delete, last.Method); @@ -56,15 +54,13 @@ public async Task DeleteWithBoolFalse_SerializesAsFalse() httpMock.MockResponse( HttpMethod.Delete, - "/authorization/organizations/org_1/resources/file/ext_42", + "/authorization/resources/res_1", HttpStatusCode.NoContent, "{}"); - await client.Authorization.DeleteResourceByExternalId( - "org_1", - "file", - "ext_42", - new AuthorizationDeleteResourceByExternalIdOptions { CascadeDelete = false }); + await client.Authorization.DeleteResource( + "res_1", + new AuthorizationDeleteResourceOptions { CascadeDelete = false }); var last = Assert.Single(httpMock.CapturedRequests); Assert.Contains("cascade_delete=false", last.RequestUri!.Query); From fe148b27d86ac3b6c839e5a45a8e25a2e5f675ab Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 27 Apr 2026 17:23:52 -0400 Subject: [PATCH 3/3] fix: Restore default desc ordering for list endpoints Keep Order nullable (callers can set null to omit it) but default to PaginationOrder.Desc so existing callers that don't set Order explicitly still get order=desc on the wire. --- src/WorkOS.net/Services/_common/_interfaces/ListOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WorkOS.net/Services/_common/_interfaces/ListOptions.cs b/src/WorkOS.net/Services/_common/_interfaces/ListOptions.cs index 3c342454..49e96a6c 100644 --- a/src/WorkOS.net/Services/_common/_interfaces/ListOptions.cs +++ b/src/WorkOS.net/Services/_common/_interfaces/ListOptions.cs @@ -35,6 +35,6 @@ public class ListOptions : BaseOptions /// [JsonProperty("order")] [STJS.JsonPropertyName("order")] - public PaginationOrder? Order { get; set; } + public PaginationOrder? Order { get; set; } = PaginationOrder.Desc; } }