• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rwjdk / TrelloDotNet / 21438348630

28 Jan 2026 12:32PM UTC coverage: 80.629% (-0.02%) from 80.649%
21438348630

push

github

rwjdk
WIP

2598 of 3512 branches covered (73.97%)

Branch coverage included in aggregate %.

4586 of 5398 relevant lines covered (84.96%)

129.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.7
/src/TrelloDotNet/TrelloClient.Members.cs
1
using System.Collections.Generic;
2
using System.Linq;
3
using System.Threading;
4
using System.Threading.Tasks;
5
using TrelloDotNet.Control;
6
using TrelloDotNet.Model;
7
using TrelloDotNet.Model.Options.GetMemberOptions;
8

9
// ReSharper disable UnusedMember.Global
10

11
namespace TrelloDotNet
12
{
13
    public partial class TrelloClient
14
    {
15
        /// <summary>
16
        /// Retrieves all members (users) of a specific board.
17
        /// </summary>
18
        /// <param name="boardId">ID of the board </param>
19
        /// <param name="cancellationToken">Cancellation Token</param>
20
        /// <returns>List of members on the board</returns>
21
        public async Task<List<Member>> GetMembersOfBoardAsync(string boardId, CancellationToken cancellationToken = default)
22
        {
23
            return await _apiRequestController.Get<List<Member>>(GetUrlBuilder.GetMembersOfBoard(boardId), cancellationToken);
27✔
24
        }
27✔
25

26
        /// <summary>
27
        /// Retrieves all members (users) of a specific board, with additional options for member data selection.
28
        /// </summary>
29
        /// <param name="boardId">ID of the board</param>
30
        /// <param name="options">Options for what data to include on the member</param>
31
        /// <param name="cancellationToken">Cancellation Token</param>
32
        /// <returns>List of members on the board</returns>
33
        public async Task<List<Member>> GetMembersOfBoardAsync(string boardId, GetMemberOptions options, CancellationToken cancellationToken = default)
34
        {
35
            if (options == null)
2✔
36
            {
37
                return await GetMembersOfBoardAsync(boardId, cancellationToken);
1✔
38
            }
39

40
            return await _apiRequestController.Get<List<Member>>(GetUrlBuilder.GetMembersOfBoard(boardId), cancellationToken, options.GetParameters());
1✔
41
        }
2✔
42

43
        /// <summary>
44
        /// Retrieves all members (users) who voted on a specific card.
45
        /// </summary>
46
        /// <param name="cardId">ID of the card</param>
47
        /// <param name="cancellationToken">Cancellation Token</param>
48
        /// <returns>List of members who voted on the card</returns>
49
        public async Task<List<Member>> GetMembersWhoVotedOnCardAsync(string cardId, CancellationToken cancellationToken = default)
50
        {
51
            return await _apiRequestController.Get<List<Member>>(GetUrlBuilder.GetMembersWhoVotedOnOfCard(cardId), cancellationToken);
2✔
52
        }
2✔
53

54
        /// <summary>
55
        /// Retrieves all members (users) who voted on a specific card, with additional options for member data selection.
56
        /// </summary>
57
        /// <param name="cardId">ID of the card</param>
58
        /// <param name="options">Options for what data to include on the member</param>
59
        /// <param name="cancellationToken">Cancellation Token</param>
60
        /// <returns>List of members who voted on the card</returns>
61
        public async Task<List<Member>> GetMembersWhoVotedOnCardAsync(string cardId, GetMemberOptions options, CancellationToken cancellationToken = default)
62
        {
63
            if (options == null)
2✔
64
            {
65
                return await GetMembersWhoVotedOnCardAsync(cardId, cancellationToken);
1✔
66
            }
67

68
            return await _apiRequestController.Get<List<Member>>(GetUrlBuilder.GetMembersWhoVotedOnOfCard(cardId), cancellationToken, options.GetParameters());
1✔
69
        }
2✔
70

71
        /// <summary>
72
        /// Retrieves all members (users) assigned to a specific card.
73
        /// </summary>
74
        /// <param name="cardId">ID of the card</param>
75
        /// <param name="cancellationToken">Cancellation Token</param>
76
        /// <returns>List of members assigned to the card</returns>
77
        public async Task<List<Member>> GetMembersOfCardAsync(string cardId, CancellationToken cancellationToken = default)
78
        {
79
            return await _apiRequestController.Get<List<Member>>(GetUrlBuilder.GetMembersOfCard(cardId), cancellationToken);
3✔
80
        }
3✔
81

82
        /// <summary>
83
        /// Retrieves all members (users) assigned to a specific card, with additional options for member data selection.
84
        /// </summary>
85
        /// <param name="cardId">ID of the card</param>
86
        /// <param name="options">Options for what data to include on the member</param>
87
        /// <param name="cancellationToken">Cancellation Token</param>
88
        /// <returns>List of members assigned to the card</returns>
89
        public async Task<List<Member>> GetMembersOfCardAsync(string cardId, GetMemberOptions options, CancellationToken cancellationToken = default)
90
        {
91
            if (options == null)
2✔
92
            {
93
                return await GetMembersOfCardAsync(cardId, cancellationToken);
1✔
94
            }
95

96
            return await _apiRequestController.Get<List<Member>>(GetUrlBuilder.GetMembersOfCard(cardId), cancellationToken, options.GetParameters());
1✔
97
        }
2✔
98

99
        /// <summary>
100
        /// Retrieves a member by their ID.
101
        /// </summary>
102
        /// <param name="memberId">ID of the member to retrieve</param>
103
        /// <param name="cancellationToken">Cancellation Token</param>
104
        /// <returns>The requested member</returns>
105
        public async Task<Member> GetMemberAsync(string memberId, CancellationToken cancellationToken = default)
106
        {
107
            return await _apiRequestController.Get<Member>(GetUrlBuilder.GetMember(memberId), cancellationToken);
1✔
108
        }
1✔
109

110
        /// <summary>
111
        /// Adds one or more members to a card by their IDs.
112
        /// </summary>
113
        /// <param name="cardId">ID of the card to add members to</param>
114
        /// <param name="memberIdsToAdd">One or more IDs of members to add</param>
115
        /// <returns>The updated card with the added members</returns>
116
        public async Task<Card> AddMembersToCardAsync(string cardId, params string[] memberIdsToAdd)
117
        {
118
            return await AddMembersToCardAsync(cardId, CancellationToken.None, memberIdsToAdd);
×
119
        }
×
120

121
        /// <summary>
122
        /// Adds one or more members to a card by their IDs.
123
        /// </summary>
124
        /// <param name="cardId">ID of the card to add members to</param>
125
        /// <param name="cancellationToken">Cancellation Token</param>
126
        /// <param name="memberIdsToAdd">One or more IDs of members to add</param>
127
        /// <returns>The updated card with the added members</returns>
128
        public async Task<Card> AddMembersToCardAsync(string cardId, CancellationToken cancellationToken = default, params string[] memberIdsToAdd)
129
        {
130
            var card = await GetCardAsync(cardId, cancellationToken);
15✔
131
            var missing = memberIdsToAdd.Where(x => !card.MemberIds.Contains(x)).ToList();
30✔
132

133
            if (missing.Count == 0)
15✔
134
            {
135
                return card; //Everyone already There
1✔
136
            }
137

138
            //Need update
139
            card.MemberIds.AddRange(missing);
14✔
140
            return await UpdateCardAsync(cardId, new List<CardUpdate>
14✔
141
            {
14✔
142
                CardUpdate.Members(card.MemberIds.Distinct().ToList())
14✔
143
            }, cancellationToken);
14✔
144
        }
15✔
145

146
        /// <summary>
147
        /// Removes one or more members from a card by their IDs.
148
        /// </summary>
149
        /// <param name="cardId">ID of the card to remove members from</param>
150
        /// <param name="memberIdsToRemove">One or more IDs of members to remove</param>
151
        /// <returns>The updated card with the members removed</returns>
152
        public async Task<Card> RemoveMembersFromCardAsync(string cardId, params string[] memberIdsToRemove)
153
        {
154
            return await RemoveMembersFromCardAsync(cardId, CancellationToken.None, memberIdsToRemove);
1✔
155
        }
1✔
156

157
        /// <summary>
158
        /// Removes one or more members from a card by their IDs.
159
        /// </summary>
160
        /// <param name="cardId">ID of the card to remove members from</param>
161
        /// <param name="cancellationToken">Cancellation Token</param>
162
        /// <param name="memberIdsToRemove">One or more IDs of members to remove</param>
163
        /// <returns>The updated card with the members removed</returns>
164
        public async Task<Card> RemoveMembersFromCardAsync(string cardId, CancellationToken cancellationToken = default, params string[] memberIdsToRemove)
165
        {
166
            var card = await GetCardAsync(cardId, cancellationToken);
3✔
167
            var toRemove = memberIdsToRemove.Where(x => card.MemberIds.Contains(x)).ToList();
6✔
168
            if (toRemove.Count == 0)
3✔
169
            {
170
                return card; //Everyone not there
1✔
171
            }
172

173
            //Need update
174
            card.MemberIds = card.MemberIds.Except(toRemove).ToList();
2✔
175
            return await UpdateCardAsync(cardId, new List<CardUpdate>
2✔
176
            {
2✔
177
                CardUpdate.Members(card.MemberIds.Distinct().ToList())
2✔
178
            }, cancellationToken);
2✔
179
        }
3✔
180

181
        /// <summary>
182
        /// Removes all members from a card, leaving it without any assigned members.
183
        /// </summary>
184
        /// <param name="cardId">ID of the card to remove all members from</param>
185
        /// <param name="cancellationToken">Cancellation Token</param>
186
        /// <returns>The updated card with all members removed</returns>
187
        public async Task<Card> RemoveAllMembersFromCardAsync(string cardId, CancellationToken cancellationToken = default)
188
        {
189
            return await UpdateCardAsync(cardId, new List<CardUpdate>
2✔
190
            {
2✔
191
                CardUpdate.Members(new List<string>())
2✔
192
            }, cancellationToken);
2✔
193
        }
2✔
194

195
        /// <summary>
196
        /// Adds a member to a board, granting them access with the specified membership type.
197
        /// </summary>
198
        /// <param name="boardId">ID of the board to grant access to</param>
199
        /// <param name="memberId">ID of the member to grant access</param>
200
        /// <param name="membershipType">The type of access to grant (admin, normal, observer, etc.)</param>
201
        /// <param name="allowBillableGuest">Optional parameter to allow organization admins to add multi-board guests to a board</param>
202
        /// <param name="cancellationToken">Cancellation Token</param>
203
        public async Task AddMemberToBoardAsync(string boardId, string memberId, MembershipType membershipType, bool allowBillableGuest = false, CancellationToken cancellationToken = default)
204
        {
205
            await _apiRequestController.Put($"{UrlPaths.Boards}/{boardId}/{UrlPaths.Members}/{memberId}", cancellationToken, 0,
1✔
206
                new QueryParameter("type", membershipType.GetJsonPropertyName()),
1✔
207
                new QueryParameter("allowBillableGuest", allowBillableGuest));
1✔
208
        }
1✔
209

210
        /// <summary>
211
        /// Invites a member to a board via email, granting them access with the specified membership type.
212
        /// </summary>
213
        /// <param name="boardId">ID of the board to invite the member to</param>
214
        /// <param name="email">Email address to send the invitation to</param>
215
        /// <param name="membershipType">The type of access to grant (normal or observer)</param>
216
        /// <param name="cancellationToken">Cancellation Token</param>
217
        public async Task InviteMemberToBoardViaEmailAsync(string boardId, string email, MembershipType membershipType, CancellationToken cancellationToken = default)
218
        {
219
            if (membershipType == MembershipType.Admin)
1!
220
            {
221
                throw new TrelloApiException($"It is not possible in the API to invite a member as 'Admin'. Instead invite as Normal and once they have accepted and email is confirmed, use '{nameof(UpdateMembershipTypeOfMemberOnBoardAsync)}' to promote them to Admin");
×
222
            }
223

224
            await _apiRequestController.Put($"{UrlPaths.Boards}/{boardId}/{UrlPaths.Members}", cancellationToken, 0,
1✔
225
                new QueryParameter("type", membershipType.GetJsonPropertyName()),
1✔
226
                new QueryParameter("email", email));
1✔
227
        }
1✔
228

229
        /// <summary>
230
        /// Removes a member from a board, revoking their access.
231
        /// </summary>
232
        /// <param name="boardId">ID of the board to remove the member from</param>
233
        /// <param name="memberId">ID of the member to remove</param>
234
        /// <param name="cancellationToken">Cancellation Token</param>
235
        public async Task RemoveMemberFromBoardAsync(string boardId, string memberId, CancellationToken cancellationToken = default)
236
        {
237
            await _apiRequestController.Delete($"{UrlPaths.Boards}/{boardId}/{UrlPaths.Members}/{memberId}", cancellationToken, 0);
1✔
238
        }
1✔
239

240
        /// <summary>
241
        /// Retrieves information about the member that owns the token used by this TrelloClient.
242
        /// </summary>
243
        /// <param name="cancellationToken">Cancellation Token</param>
244
        /// <returns>The member that owns the token</returns>
245
        public async Task<Member> GetTokenMemberAsync(CancellationToken cancellationToken = default)
246
        {
247
            return await _apiRequestController.Get<Member>(GetUrlBuilder.GetTokenMember(_apiRequestController.Token), cancellationToken);
24✔
248
        }
24✔
249

250
        /// <summary>
251
        /// Retrieves information about the member that owns the token used by this TrelloClient, with additional options for member data selection.
252
        /// </summary>
253
        /// <param name="options">Options for what data to include on the member</param>
254
        /// <param name="cancellationToken">Cancellation Token</param>
255
        /// <returns>The member that owns the token</returns>
256
        public async Task<Member> GetTokenMemberAsync(GetMemberOptions options, CancellationToken cancellationToken = default)
257
        {
258
            if (options == null)
2✔
259
            {
260
                return await GetTokenMemberAsync(cancellationToken);
1✔
261
            }
262

263
            return await _apiRequestController.Get<Member>(GetUrlBuilder.GetTokenMember(_apiRequestController.Token), cancellationToken, options.GetParameters());
1✔
264
        }
2✔
265

266
        /// <summary>
267
        /// Retrieves all members (users) of a specific organization (workspace).
268
        /// </summary>
269
        /// <param name="organizationId">ID of the organization (workspace)</param>
270
        /// <param name="cancellationToken">Cancellation Token</param>
271
        /// <returns>List of members in the organization</returns>
272
        public async Task<List<Member>> GetMembersOfOrganizationAsync(string organizationId, CancellationToken cancellationToken = default)
273
        {
274
            return await _apiRequestController.Get<List<Member>>(GetUrlBuilder.GetMembersOfOrganization(organizationId), cancellationToken);
2✔
275
        }
2✔
276

277
        /// <summary>
278
        /// Retrieves all members (users) of a specific organization (workspace), with additional options for member data selection.
279
        /// </summary>
280
        /// <param name="organizationId">ID of the organization (workspace)</param>
281
        /// <param name="options">Options for what data to include on the member</param>
282
        /// <param name="cancellationToken">Cancellation Token</param>
283
        /// <returns>List of members in the organization</returns>
284
        public async Task<List<Member>> GetMembersOfOrganizationAsync(string organizationId, GetMemberOptions options, CancellationToken cancellationToken = default)
285
        {
286
            if (options == null)
2✔
287
            {
288
                return await GetMembersOfOrganizationAsync(organizationId, cancellationToken);
1✔
289
            }
290

291
            return await _apiRequestController.Get<List<Member>>(GetUrlBuilder.GetMembersOfOrganization(organizationId), cancellationToken, options.GetParameters());
1✔
292
        }
2✔
293

294
        /// <summary>
295
        /// Adds a member vote to a card.
296
        /// </summary>
297
        /// <param name="cardId">ID of the card to add the vote to</param>
298
        /// <param name="memberId">ID of the member casting the vote</param>
299
        /// <param name="cancellationToken">Cancellation Token</param>
300
        public async Task AddVoteToCardAsync(string cardId, string memberId, CancellationToken cancellationToken = default)
301
        {
302
            await _apiRequestController.Post($"{UrlPaths.Cards}/{cardId}/membersVoted", cancellationToken, 0, new QueryParameter("value", memberId));
1✔
303
        }
1✔
304

305
        /// <summary>
306
        /// Removes a member vote from a card.
307
        /// </summary>
308
        /// <param name="cardId">ID of the card to remove the vote from</param>
309
        /// <param name="memberId">ID of the member whose vote should be removed</param>
310
        /// <param name="cancellationToken">Cancellation Token</param>
311
        public async Task RemoveVoteFromCardAsync(string cardId, string memberId, CancellationToken cancellationToken = default)
312
        {
313
            await _apiRequestController.Delete($"{UrlPaths.Cards}/{cardId}/membersVoted/{memberId}", cancellationToken, 0);
1✔
314
        }
1✔
315
    }
316
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc