From 97255b320b30057b4453452732b26126ad2c816d Mon Sep 17 00:00:00 2001 From: Andrzej Bansleben Date: Sat, 12 Sep 2026 23:19:46 +0200 Subject: [PATCH 1/8] Refactor role handling: Introduce JsonPartialRole and IPartialRole interface for improved deserialization --- NetCord/IPartialRole.cs | 25 +++++++ NetCord/JsonModels/JsonRole.cs | 29 +++++++-- NetCord/Rest/JsonModels/JsonRestInvite.cs | 2 +- NetCord/Rest/RestInvite.cs | 4 +- NetCord/Role.cs | 79 ++++++++++++++++++++++- 5 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 NetCord/IPartialRole.cs diff --git a/NetCord/IPartialRole.cs b/NetCord/IPartialRole.cs new file mode 100644 index 000000000..bd869f981 --- /dev/null +++ b/NetCord/IPartialRole.cs @@ -0,0 +1,25 @@ +using System.ComponentModel; + +namespace NetCord; + +public interface IPartialRole +{ + + ulong Id { get; } + + string Name { get; } + + RolePosition Position { get; } + + [EditorBrowsable(EditorBrowsableState.Never)] + Color Color { get; } + + RoleColors Colors { get; } + + int RawPosition { get; } + + string? IconHash { get; } + + string? UnicodeEmoji { get; } + +} diff --git a/NetCord/JsonModels/JsonRole.cs b/NetCord/JsonModels/JsonRole.cs index 87cf34ed1..00344b1d1 100644 --- a/NetCord/JsonModels/JsonRole.cs +++ b/NetCord/JsonModels/JsonRole.cs @@ -1,26 +1,43 @@ +using System.ComponentModel; using System.Text.Json.Serialization; namespace NetCord.JsonModels; -public class JsonRole : JsonEntity +/// +/// Represents a partial role. +/// +/// +/// This class is used when a role is returned in a context where not all properties are available, i.e. in . +/// +public class JsonPartialRole : JsonEntity { [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("position")] + public int Position { get; set; } + + [EditorBrowsable(EditorBrowsableState.Never)] + [JsonPropertyName("color")] + public Color Color { get; set; } + [JsonPropertyName("colors")] public JsonRoleColors Colors { get; set; } - [JsonPropertyName("hoist")] - public bool Hoist { get; set; } - [JsonPropertyName("icon")] public string? IconHash { get; set; } [JsonPropertyName("unicode_emoji")] public string? UnicodeEmoji { get; set; } +} - [JsonPropertyName("position")] - public int Position { get; set; } +/// +/// Represents a full role in a guild with all properties available. +/// +public class JsonRole : JsonPartialRole +{ + [JsonPropertyName("hoist")] + public bool Hoist { get; set; } [JsonPropertyName("permissions")] public Permissions Permissions { get; set; } diff --git a/NetCord/Rest/JsonModels/JsonRestInvite.cs b/NetCord/Rest/JsonModels/JsonRestInvite.cs index fd007431d..8684171a2 100644 --- a/NetCord/Rest/JsonModels/JsonRestInvite.cs +++ b/NetCord/Rest/JsonModels/JsonRestInvite.cs @@ -46,7 +46,7 @@ public class JsonRestInvite public InviteFlags? Flags { get; set; } [JsonPropertyName("roles")] - public JsonRole[]? Roles { get; set; } + public JsonPartialRole[]? Roles { get; set; } [JsonPropertyName("uses")] public int? Uses { get; set; } diff --git a/NetCord/Rest/RestInvite.cs b/NetCord/Rest/RestInvite.cs index 18be1a36a..d4430e2da 100644 --- a/NetCord/Rest/RestInvite.cs +++ b/NetCord/Rest/RestInvite.cs @@ -33,7 +33,7 @@ public partial class RestInvite : IInvite, IJsonModel public InviteFlags? Flags => _jsonModel.Flags; - public IReadOnlyList? Roles { get; } + public IReadOnlyList? Roles { get; } // Metadata public int? Uses => _jsonModel.Uses; @@ -61,7 +61,7 @@ public RestInvite(JsonModels.JsonRestInvite jsonModel, RestClient client) var guildId = Guild.Id; if (jsonModel.Roles is { } roles) - Roles = roles.Select(role => new Role(role, guildId, client)).ToArray(); + Roles = roles.Select(role => new PartialRole(role)).ToArray(); } if (jsonModel.Channel is { } channel) diff --git a/NetCord/Role.cs b/NetCord/Role.cs index 0107ac91b..53ddde505 100644 --- a/NetCord/Role.cs +++ b/NetCord/Role.cs @@ -1,12 +1,78 @@ +using System.ComponentModel; + using NetCord.JsonModels; using NetCord.Rest; namespace NetCord; /// -/// Represents a role in a guild. +/// Represents a partial role. +/// +public class PartialRole : Entity, IPartialRole, IJsonModel +{ + JsonPartialRole IJsonModel.JsonModel => _jsonModel; + private readonly JsonPartialRole _jsonModel; + + /// + /// The 's ID. + /// + public override ulong Id => _jsonModel.Id; + + /// + /// The name of the . + /// + public string Name => _jsonModel.Name; + + /// + /// The color of the . + /// + /// + /// This will still be returned by the API, but using is recommended when doing requests. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Color Color => _jsonModel.Color; + + /// + /// The 's colors. + /// + public RoleColors Colors { get; } + + /// + /// The raw position of this . + /// + /// + /// Use to get a properly comparable and sortable position value. + /// + public int RawPosition => _jsonModel.Position; + + /// + /// The position of this for sorting and comparing. + /// + public RolePosition Position => new(RawPosition, Id); + + /// + /// The 's icon hash. + /// + public string? IconHash => _jsonModel.IconHash; + + /// + /// The 's Unicode emoji. + /// + public string? UnicodeEmoji => _jsonModel.UnicodeEmoji; + public override string ToString() => $"<@&{Id}>"; + + public PartialRole(JsonPartialRole jsonModel) + { + _jsonModel = jsonModel; + + Colors = new(jsonModel.Colors); + } +} + +/// +/// Represents a full role in a guild. /// -public partial class Role : ClientEntity, IJsonModel +public partial class Role : ClientEntity, IPartialRole, IJsonModel { JsonRole IJsonModel.JsonModel => _jsonModel; private readonly JsonRole _jsonModel; @@ -21,6 +87,15 @@ public partial class Role : ClientEntity, IJsonModel /// public string Name => _jsonModel.Name; + /// + /// The color of the . + /// + /// + /// This will still be returned by the API, but using is recommended when doing requests. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Color Color => _jsonModel.Color; + /// /// The 's colors. /// From 82e145a90c5e75c3b5001e14601abe7f79986590 Mon Sep 17 00:00:00 2001 From: Andrzej Bansleben Date: Sun, 13 Sep 2026 20:12:12 +0200 Subject: [PATCH 2/8] Reduce unnecessary abstraction and make Role inherit directly from PartialRole --- NetCord/IPartialRole.cs | 25 --------- NetCord/PartialRole.cs | 73 ++++++++++++++++++++++++++ NetCord/Role.cs | 111 +--------------------------------------- 3 files changed, 75 insertions(+), 134 deletions(-) delete mode 100644 NetCord/IPartialRole.cs create mode 100644 NetCord/PartialRole.cs diff --git a/NetCord/IPartialRole.cs b/NetCord/IPartialRole.cs deleted file mode 100644 index bd869f981..000000000 --- a/NetCord/IPartialRole.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.ComponentModel; - -namespace NetCord; - -public interface IPartialRole -{ - - ulong Id { get; } - - string Name { get; } - - RolePosition Position { get; } - - [EditorBrowsable(EditorBrowsableState.Never)] - Color Color { get; } - - RoleColors Colors { get; } - - int RawPosition { get; } - - string? IconHash { get; } - - string? UnicodeEmoji { get; } - -} diff --git a/NetCord/PartialRole.cs b/NetCord/PartialRole.cs new file mode 100644 index 000000000..db8925517 --- /dev/null +++ b/NetCord/PartialRole.cs @@ -0,0 +1,73 @@ +using System.ComponentModel; + +using NetCord.JsonModels; +using NetCord.Rest; + +namespace NetCord; + +/// +/// Represents a partial role. +/// +/// +/// Useful for . +/// +public class PartialRole : ClientEntity, IJsonModel +{ + JsonPartialRole IJsonModel.JsonModel => _jsonModel; + private readonly JsonPartialRole _jsonModel; + + /// + /// The 's ID. + /// + public override ulong Id => _jsonModel.Id; + + /// + /// The name of the . + /// + public string Name => _jsonModel.Name; + + /// + /// The color of the . + /// + /// + /// This will still be returned by the API, but using is recommended when doing requests. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Color Color => _jsonModel.Color; + + /// + /// The 's colors. + /// + public RoleColors Colors { get; } + + /// + /// The raw position of this . + /// + /// + /// Use to get a properly comparable and sortable position value. + /// + public int RawPosition => _jsonModel.Position; + + /// + /// The position of this for sorting and comparing. + /// + public RolePosition Position => new(RawPosition, Id); + + /// + /// The 's icon hash. + /// + public string? IconHash => _jsonModel.IconHash; + + /// + /// The 's Unicode emoji. + /// + public string? UnicodeEmoji => _jsonModel.UnicodeEmoji; + public override string ToString() => $"<@&{Id}>"; + + public PartialRole(JsonRole jsonModel, RestClient client) : base(client) + { + _jsonModel = jsonModel; + + Colors = new(jsonModel.Colors); + } +} diff --git a/NetCord/Role.cs b/NetCord/Role.cs index 53ddde505..ab493d045 100644 --- a/NetCord/Role.cs +++ b/NetCord/Role.cs @@ -5,74 +5,11 @@ namespace NetCord; -/// -/// Represents a partial role. -/// -public class PartialRole : Entity, IPartialRole, IJsonModel -{ - JsonPartialRole IJsonModel.JsonModel => _jsonModel; - private readonly JsonPartialRole _jsonModel; - - /// - /// The 's ID. - /// - public override ulong Id => _jsonModel.Id; - - /// - /// The name of the . - /// - public string Name => _jsonModel.Name; - - /// - /// The color of the . - /// - /// - /// This will still be returned by the API, but using is recommended when doing requests. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public Color Color => _jsonModel.Color; - - /// - /// The 's colors. - /// - public RoleColors Colors { get; } - - /// - /// The raw position of this . - /// - /// - /// Use to get a properly comparable and sortable position value. - /// - public int RawPosition => _jsonModel.Position; - - /// - /// The position of this for sorting and comparing. - /// - public RolePosition Position => new(RawPosition, Id); - - /// - /// The 's icon hash. - /// - public string? IconHash => _jsonModel.IconHash; - - /// - /// The 's Unicode emoji. - /// - public string? UnicodeEmoji => _jsonModel.UnicodeEmoji; - public override string ToString() => $"<@&{Id}>"; - - public PartialRole(JsonPartialRole jsonModel) - { - _jsonModel = jsonModel; - - Colors = new(jsonModel.Colors); - } -} /// /// Represents a full role in a guild. /// -public partial class Role : ClientEntity, IPartialRole, IJsonModel +public partial class Role : PartialRole, IJsonModel { JsonRole IJsonModel.JsonModel => _jsonModel; private readonly JsonRole _jsonModel; @@ -82,53 +19,11 @@ public partial class Role : ClientEntity, IPartialRole, IJsonModel /// public override ulong Id => _jsonModel.Id; - /// - /// The name of the . - /// - public string Name => _jsonModel.Name; - - /// - /// The color of the . - /// - /// - /// This will still be returned by the API, but using is recommended when doing requests. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public Color Color => _jsonModel.Color; - - /// - /// The 's colors. - /// - public RoleColors Colors { get; } - /// /// Whether this causes users with it to be displayed in a separate section in the guild users list. /// public bool Hoist => _jsonModel.Hoist; - /// - /// The 's icon hash. - /// - public string? IconHash => _jsonModel.IconHash; - - /// - /// The 's Unicode emoji. - /// - public string? UnicodeEmoji => _jsonModel.UnicodeEmoji; - - /// - /// The raw position of this . - /// - /// - /// Use to get a properly comparable and sortable position value. - /// - public int RawPosition => _jsonModel.Position; - - /// - /// The position of this for sorting and comparing. - /// - public RolePosition Position => new(RawPosition, Id); - /// /// The permission bit set for this . /// @@ -159,12 +54,10 @@ public partial class Role : ClientEntity, IPartialRole, IJsonModel /// public ulong GuildId { get; } - public Role(JsonRole jsonModel, ulong guildId, RestClient client) : base(client) + public Role(JsonRole jsonModel, ulong guildId, RestClient client) : base(jsonModel, client) { _jsonModel = jsonModel; - Colors = new(jsonModel.Colors); - if (jsonModel.Tags is { } tags) Tags = new(tags); From f48c940137b923bb93b5b2885102edc7c759ec34 Mon Sep 17 00:00:00 2001 From: Andrzej Bansleben Date: Sun, 13 Sep 2026 20:21:41 +0200 Subject: [PATCH 3/8] Fix PartialRole initialisation arguments, constructor argument wrong type and use `partial` keyword for the class declaration --- NetCord/PartialRole.cs | 4 ++-- NetCord/Rest/RestInvite.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NetCord/PartialRole.cs b/NetCord/PartialRole.cs index db8925517..a120a443c 100644 --- a/NetCord/PartialRole.cs +++ b/NetCord/PartialRole.cs @@ -11,7 +11,7 @@ namespace NetCord; /// /// Useful for . /// -public class PartialRole : ClientEntity, IJsonModel +public partial class PartialRole : ClientEntity, IJsonModel { JsonPartialRole IJsonModel.JsonModel => _jsonModel; private readonly JsonPartialRole _jsonModel; @@ -64,7 +64,7 @@ public class PartialRole : ClientEntity, IJsonModel public string? UnicodeEmoji => _jsonModel.UnicodeEmoji; public override string ToString() => $"<@&{Id}>"; - public PartialRole(JsonRole jsonModel, RestClient client) : base(client) + public PartialRole(JsonPartialRole jsonModel, RestClient client) : base(client) { _jsonModel = jsonModel; diff --git a/NetCord/Rest/RestInvite.cs b/NetCord/Rest/RestInvite.cs index d4430e2da..c2d897790 100644 --- a/NetCord/Rest/RestInvite.cs +++ b/NetCord/Rest/RestInvite.cs @@ -61,7 +61,7 @@ public RestInvite(JsonModels.JsonRestInvite jsonModel, RestClient client) var guildId = Guild.Id; if (jsonModel.Roles is { } roles) - Roles = roles.Select(role => new PartialRole(role)).ToArray(); + Roles = roles.Select(role => new PartialRole(role, client)).ToArray(); } if (jsonModel.Channel is { } channel) From 841eeea9c07d08dc9e7ab6ff542a5b71ce974baf Mon Sep 17 00:00:00 2001 From: Andrzej Bansleben Date: Sun, 13 Sep 2026 20:27:40 +0200 Subject: [PATCH 4/8] Add GuildId property on PartialRole, and universalise xml comments for correct documentation inheritance --- NetCord/PartialRole.cs | 25 +++++++++++++-------- NetCord/Rest/RestInvite.cs | 2 +- NetCord/Role.cs | 45 ++++++++++++++++---------------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/NetCord/PartialRole.cs b/NetCord/PartialRole.cs index a120a443c..88b1bc3c2 100644 --- a/NetCord/PartialRole.cs +++ b/NetCord/PartialRole.cs @@ -17,17 +17,17 @@ public partial class PartialRole : ClientEntity, IJsonModel private readonly JsonPartialRole _jsonModel; /// - /// The 's ID. + /// The role's ID. /// public override ulong Id => _jsonModel.Id; /// - /// The name of the . + /// The name of the role. /// public string Name => _jsonModel.Name; /// - /// The color of the . + /// The color of the role. /// /// /// This will still be returned by the API, but using is recommended when doing requests. @@ -36,12 +36,12 @@ public partial class PartialRole : ClientEntity, IJsonModel public Color Color => _jsonModel.Color; /// - /// The 's colors. + /// The role's colors. /// public RoleColors Colors { get; } /// - /// The raw position of this . + /// The raw position of this role. /// /// /// Use to get a properly comparable and sortable position value. @@ -49,25 +49,32 @@ public partial class PartialRole : ClientEntity, IJsonModel public int RawPosition => _jsonModel.Position; /// - /// The position of this for sorting and comparing. + /// The position of this role for sorting and comparing. /// public RolePosition Position => new(RawPosition, Id); /// - /// The 's icon hash. + /// The role's icon hash. /// public string? IconHash => _jsonModel.IconHash; /// - /// The 's Unicode emoji. + /// The role's Unicode emoji. /// public string? UnicodeEmoji => _jsonModel.UnicodeEmoji; + + /// + /// The ID of the guild this role belongs to. + /// + public ulong GuildId { get; } public override string ToString() => $"<@&{Id}>"; - public PartialRole(JsonPartialRole jsonModel, RestClient client) : base(client) + public PartialRole(JsonPartialRole jsonModel, ulong guildId, RestClient client) : base(client) { _jsonModel = jsonModel; Colors = new(jsonModel.Colors); + + GuildId = guildId; } } diff --git a/NetCord/Rest/RestInvite.cs b/NetCord/Rest/RestInvite.cs index c2d897790..90cb6061d 100644 --- a/NetCord/Rest/RestInvite.cs +++ b/NetCord/Rest/RestInvite.cs @@ -61,7 +61,7 @@ public RestInvite(JsonModels.JsonRestInvite jsonModel, RestClient client) var guildId = Guild.Id; if (jsonModel.Roles is { } roles) - Roles = roles.Select(role => new PartialRole(role, client)).ToArray(); + Roles = roles.Select(role => new PartialRole(role, guildId, client)).ToArray(); } if (jsonModel.Channel is { } channel) diff --git a/NetCord/Role.cs b/NetCord/Role.cs index ab493d045..fd99160fe 100644 --- a/NetCord/Role.cs +++ b/NetCord/Role.cs @@ -15,57 +15,50 @@ public partial class Role : PartialRole, IJsonModel private readonly JsonRole _jsonModel; /// - /// The 's ID. + /// The role's ID. /// public override ulong Id => _jsonModel.Id; /// - /// Whether this causes users with it to be displayed in a separate section in the guild users list. + /// Whether this role causes users with it to be displayed in a separate section in the guild users list. /// public bool Hoist => _jsonModel.Hoist; /// - /// The permission bit set for this . + /// The permission bit set for this role. /// public Permissions Permissions => _jsonModel.Permissions; /// - /// Whether this is managed by an integration. + /// Whether this role is managed by an integration. /// public bool Managed => _jsonModel.Managed; /// - /// Whether this is mentionable. + /// Whether this role is mentionable. /// public bool Mentionable => _jsonModel.Mentionable; /// - /// The tags this has. + /// The tags this role has. /// public RoleTags? Tags { get; } /// - /// The 's flags combined as a bitfield. + /// The role's flags combined as a bitfield. /// public RoleFlags Flags => _jsonModel.Flags; - /// - /// The ID of the guild this belongs to. - /// - public ulong GuildId { get; } - - public Role(JsonRole jsonModel, ulong guildId, RestClient client) : base(jsonModel, client) + public Role(JsonRole jsonModel, ulong guildId, RestClient client) : base(jsonModel, guildId, client) { _jsonModel = jsonModel; if (jsonModel.Tags is { } tags) Tags = new(tags); - - GuildId = guildId; } /// - /// Gets the of the 's icon. + /// Gets the of the role's icon. /// /// The format of the returned . /// An pointing to the role's icon. If the role does not have one set, returns . @@ -77,19 +70,19 @@ public Role(JsonRole jsonModel, ulong guildId, RestClient client) : base(jsonMod } /// -/// Represents the colors of a . +/// Represents the colors of a role. /// public class RoleColors(JsonRoleColors jsonModel) : IJsonModel { JsonRoleColors IJsonModel.JsonModel => jsonModel; /// - /// The primary color for the . + /// The primary color for the role. /// public Color PrimaryColor => jsonModel.PrimaryColor; /// - /// The secondary color for the . This will make the role a gradient between the other provided colors. + /// The secondary color for the role. This will make the role a gradient between the other provided colors. /// /// /// Requires the guild to have the ENHANCED_ROLE_COLORS guild feature. @@ -97,7 +90,7 @@ public class RoleColors(JsonRoleColors jsonModel) : IJsonModel public Color? SecondaryColor => jsonModel.SecondaryColor; /// - /// The tertiary color for the . This will turn the gradient into a holographic style. + /// The tertiary color for the role. This will turn the gradient into a holographic style. /// /// /// Requires the guild to have the ENHANCED_ROLE_COLORS guild feature. @@ -106,19 +99,19 @@ public class RoleColors(JsonRoleColors jsonModel) : IJsonModel } /// -/// Represents the tags associated with a . +/// Represents the tags associated with a role. /// public class RoleTags(JsonRoleTags jsonModel) : IJsonModel { JsonRoleTags IJsonModel.JsonModel => jsonModel; /// - /// The ID of the bot this belongs to. + /// The ID of the bot this role belongs to. /// public ulong? BotId => jsonModel.BotId; /// - /// The ID of the integration this belongs to. + /// The ID of the integration this role belongs to. /// public ulong? IntegrationId => jsonModel.IntegrationId; @@ -128,17 +121,17 @@ public class RoleTags(JsonRoleTags jsonModel) : IJsonModel public bool IsPremiumSubscriber => jsonModel.IsPremiumSubscriber; /// - /// The ID of this 's subscription SKU and listing. + /// The ID of this role's subscription SKU and listing. /// public ulong? SubscriptionListingId => jsonModel.SubscriptionListingId; /// - /// Whether this is available for purchase. + /// Whether this role is available for purchase. /// public bool IsAvailableForPurchase => jsonModel.IsAvailableForPurchase; /// - /// Whether this is a guild's linked role. + /// Whether this role is a guild's linked role. /// public bool GuildConnections => jsonModel.GuildConnections; } From 5dc038c3038141e8a2596ed8ee286879c33e51c0 Mon Sep 17 00:00:00 2001 From: Andrzej Bansleben Date: Sun, 13 Sep 2026 20:29:24 +0200 Subject: [PATCH 5/8] Add generated aliases for PartialRole --- NetCord/Rest/RestClient.Guild.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NetCord/Rest/RestClient.Guild.cs b/NetCord/Rest/RestClient.Guild.cs index eb62e537f..96fcb1ac3 100644 --- a/NetCord/Rest/RestClient.Guild.cs +++ b/NetCord/Rest/RestClient.Guild.cs @@ -198,6 +198,7 @@ public async Task> ModifyGuildRolePositionsAsync(ulong guild [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] + [GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(PartialRole)}")] public async Task ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { RoleOptions obj = new(); @@ -208,6 +209,7 @@ public async Task ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] + [GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(PartialRole)}")] public Task DeleteGuildRoleAsync(ulong guildId, ulong roleId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}/roles/{roleId}", null, new(guildId), properties, cancellationToken: cancellationToken); From 2715e06a8299f8d074ab8470f5e2f834d76aec51 Mon Sep 17 00:00:00 2001 From: Andrzej Bansleben Date: Sun, 13 Sep 2026 20:40:59 +0200 Subject: [PATCH 6/8] Fix type name override for PartialRole aliases, and cosmetic --- NetCord/PartialRole.cs | 1 + NetCord/Rest/RestClient.Guild.cs | 4 ++-- NetCord/Role.cs | 3 --- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/NetCord/PartialRole.cs b/NetCord/PartialRole.cs index 88b1bc3c2..1d7c7e0c3 100644 --- a/NetCord/PartialRole.cs +++ b/NetCord/PartialRole.cs @@ -67,6 +67,7 @@ public partial class PartialRole : ClientEntity, IJsonModel /// The ID of the guild this role belongs to. /// public ulong GuildId { get; } + public override string ToString() => $"<@&{Id}>"; public PartialRole(JsonPartialRole jsonModel, ulong guildId, RestClient client) : base(client) diff --git a/NetCord/Rest/RestClient.Guild.cs b/NetCord/Rest/RestClient.Guild.cs index 96fcb1ac3..68c138d0e 100644 --- a/NetCord/Rest/RestClient.Guild.cs +++ b/NetCord/Rest/RestClient.Guild.cs @@ -198,7 +198,7 @@ public async Task> ModifyGuildRolePositionsAsync(ulong guild [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] - [GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(PartialRole)}")] + [GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] public async Task ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { RoleOptions obj = new(); @@ -209,7 +209,7 @@ public async Task ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] - [GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(PartialRole)}")] + [GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] public Task DeleteGuildRoleAsync(ulong guildId, ulong roleId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}/roles/{roleId}", null, new(guildId), properties, cancellationToken: cancellationToken); diff --git a/NetCord/Role.cs b/NetCord/Role.cs index fd99160fe..5ce7824e0 100644 --- a/NetCord/Role.cs +++ b/NetCord/Role.cs @@ -1,11 +1,8 @@ -using System.ComponentModel; - using NetCord.JsonModels; using NetCord.Rest; namespace NetCord; - /// /// Represents a full role in a guild. /// From 088f03a2ba1111da7a46e611c5006b8a4779a303 Mon Sep 17 00:00:00 2001 From: Andrzej Bansleben Date: Mon, 14 Sep 2026 09:32:15 +0200 Subject: [PATCH 7/8] Remove duplicate GenerateAlias for Role Removed duplicate GenerateAlias attribute for Role in ModifyGuildRoleAsync method. --- NetCord/Rest/RestClient.Guild.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/NetCord/Rest/RestClient.Guild.cs b/NetCord/Rest/RestClient.Guild.cs index 68c138d0e..92854281e 100644 --- a/NetCord/Rest/RestClient.Guild.cs +++ b/NetCord/Rest/RestClient.Guild.cs @@ -197,7 +197,6 @@ public async Task> ModifyGuildRolePositionsAsync(ulong guild } [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] - [GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] [GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] public async Task ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -208,7 +207,6 @@ public async Task ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action } [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] - [GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] [GenerateAlias([typeof(PartialRole)], nameof(PartialRole.GuildId), nameof(PartialRole.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] public Task DeleteGuildRoleAsync(ulong guildId, ulong roleId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}/roles/{roleId}", null, new(guildId), properties, cancellationToken: cancellationToken); From 483fc49300bc3a71aeada24d75ee94e20b18d8c9 Mon Sep 17 00:00:00 2001 From: Andrzej Bansleben Date: Mon, 14 Sep 2026 12:50:10 +0200 Subject: [PATCH 8/8] Remove deprecated field from JsonPartialRole and PartialRole, remove redundant XML comments, and move JsonPartialRole to a separate file --- NetCord/JsonModels/JsonPartialRole.cs | 25 ++++++++++++++++++++ NetCord/JsonModels/JsonRole.cs | 33 +-------------------------- NetCord/PartialRole.cs | 9 -------- 3 files changed, 26 insertions(+), 41 deletions(-) create mode 100644 NetCord/JsonModels/JsonPartialRole.cs diff --git a/NetCord/JsonModels/JsonPartialRole.cs b/NetCord/JsonModels/JsonPartialRole.cs new file mode 100644 index 000000000..777f40734 --- /dev/null +++ b/NetCord/JsonModels/JsonPartialRole.cs @@ -0,0 +1,25 @@ +using System.ComponentModel; +using System.Text.Json.Serialization; + +namespace NetCord.JsonModels; + +/// +/// This class is used when a role is returned in a context where not all properties are available, i.e. in . +/// +public class JsonPartialRole : JsonEntity +{ + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("position")] + public int Position { get; set; } + + [JsonPropertyName("colors")] + public JsonRoleColors Colors { get; set; } + + [JsonPropertyName("icon")] + public string? IconHash { get; set; } + + [JsonPropertyName("unicode_emoji")] + public string? UnicodeEmoji { get; set; } +} diff --git a/NetCord/JsonModels/JsonRole.cs b/NetCord/JsonModels/JsonRole.cs index 00344b1d1..de7b559bb 100644 --- a/NetCord/JsonModels/JsonRole.cs +++ b/NetCord/JsonModels/JsonRole.cs @@ -2,38 +2,7 @@ using System.Text.Json.Serialization; namespace NetCord.JsonModels; - -/// -/// Represents a partial role. -/// -/// -/// This class is used when a role is returned in a context where not all properties are available, i.e. in . -/// -public class JsonPartialRole : JsonEntity -{ - [JsonPropertyName("name")] - public string Name { get; set; } - - [JsonPropertyName("position")] - public int Position { get; set; } - - [EditorBrowsable(EditorBrowsableState.Never)] - [JsonPropertyName("color")] - public Color Color { get; set; } - - [JsonPropertyName("colors")] - public JsonRoleColors Colors { get; set; } - - [JsonPropertyName("icon")] - public string? IconHash { get; set; } - - [JsonPropertyName("unicode_emoji")] - public string? UnicodeEmoji { get; set; } -} - -/// -/// Represents a full role in a guild with all properties available. -/// + public class JsonRole : JsonPartialRole { [JsonPropertyName("hoist")] diff --git a/NetCord/PartialRole.cs b/NetCord/PartialRole.cs index 1d7c7e0c3..2c8228a14 100644 --- a/NetCord/PartialRole.cs +++ b/NetCord/PartialRole.cs @@ -26,15 +26,6 @@ public partial class PartialRole : ClientEntity, IJsonModel /// public string Name => _jsonModel.Name; - /// - /// The color of the role. - /// - /// - /// This will still be returned by the API, but using is recommended when doing requests. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public Color Color => _jsonModel.Color; - /// /// The role's colors. ///