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

loresoft / FluentRest / 19305589223

12 Nov 2025 05:07PM UTC coverage: 55.271% (-0.3%) from 55.567%
19305589223

push

github

pwelter34
#241 QueryString DateTime / DateTimeOffset

297 of 696 branches covered (42.67%)

Branch coverage included in aggregate %.

8 of 19 new or added lines in 2 files covered. (42.11%)

1 existing line in 1 file now uncovered.

825 of 1334 relevant lines covered (61.84%)

28.12 hits per line

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

38.65
/src/FluentRest/QueryBuilder.cs
1
namespace FluentRest;
2

3
/// <summary>
4
/// A fluent query builder.
5
/// </summary>
6
public class QueryBuilder : QueryBuilder<QueryBuilder>
7
{
8
    /// <summary>
9
    /// Initializes a new instance of the <see cref="QueryBuilder" /> class.
10
    /// </summary>
11
    /// <param name="requestMessage">The fluent HTTP request being built.</param>
12
    public QueryBuilder(HttpRequestMessage requestMessage) : base(requestMessage)
28✔
13
    {
14
    }
28✔
15
}
16

17
/// <summary>
18
/// A fluent query builder.
19
/// </summary>
20
/// <typeparam name="TBuilder">The type of the builder.</typeparam>
21
public abstract class QueryBuilder<TBuilder> : RequestBuilder<TBuilder>
22
    where TBuilder : QueryBuilder<TBuilder>
23
{
24
    /// <summary>
25
    /// Initializes a new instance of the <see cref="QueryBuilder{TBuilder}"/> class.
26
    /// </summary>
27
    /// <param name="requestMessage">The fluent HTTP request being built.</param>
28
    protected QueryBuilder(HttpRequestMessage requestMessage) : base(requestMessage)
65✔
29
    {
30
    }
65✔
31

32
    /// <summary>
33
    /// Start a fluent header builder.
34
    /// </summary>
35
    /// <param name="builder">The builder factory.</param>
36
    /// <returns>A fluent request builder.</returns>
37
    /// <exception cref="ArgumentNullException"><paramref name="builder" /> is <see langword="null" />.</exception>
38
    public TBuilder Header(Action<HeaderBuilder> builder)
39
    {
40
        if (builder is null)
8!
41
            throw new ArgumentNullException(nameof(builder));
×
42

43
        var headerBuilder = new HeaderBuilder(RequestMessage);
8✔
44
        builder(headerBuilder);
8✔
45

46
        return (TBuilder)this;
8✔
47
    }
48

49
    /// <summary>
50
    /// Sets HTTP header with the specified <paramref name="name"/> and <paramref name="value"/>.
51
    /// </summary>
52
    /// <param name="name">The header name.</param>
53
    /// <param name="value">The header value.</param>
54
    /// <returns>A fluent request builder.</returns>
55
    /// <exception cref="ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
56
    public TBuilder Header(string name, string? value)
57
    {
58
        if (name is null)
5!
59
            throw new ArgumentNullException(nameof(name));
×
60

61
        if (value is null)
5✔
62
            RequestMessage.Headers.Remove(name);
1✔
63
        else
64
            RequestMessage.Headers.Add(name, value);
4✔
65

66
        return (TBuilder)this;
5✔
67
    }
68

69
    /// <summary>
70
    /// Sets HTTP header with the specified <paramref name="name"/> and <paramref name="value"/> if the specified <paramref name="condition"/> is true.
71
    /// </summary>
72
    /// <param name="condition">If condition is true, header will be added; otherwise ignore header.</param>
73
    /// <param name="name">The header name.</param>
74
    /// <param name="value">The header value.</param>
75
    /// <returns>A fluent request builder.</returns>
76
    /// <exception cref="ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
77
    public TBuilder HeaderIf(Func<bool> condition, string name, string? value)
78
    {
79
        if (condition is null || !condition())
×
80
            return (TBuilder)this;
×
81

82
        return Header(name, value);
×
83
    }
84

85
    /// <summary>
86
    /// Sets HTTP header with the specified <paramref name="name"/> and <paramref name="value"/> if the specified <paramref name="condition"/> is true.
87
    /// </summary>
88
    /// <param name="condition">If condition is true, header will be added; otherwise ignore header.</param>
89
    /// <param name="name">The header name.</param>
90
    /// <param name="value">The header value.</param>
91
    /// <returns>A fluent request builder.</returns>
92
    /// <exception cref="ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
93
    public TBuilder HeaderIf(bool condition, string name, string? value)
94
    {
95
        if (!condition)
×
96
            return (TBuilder)this;
×
97

98
        return Header(name, value);
×
99
    }
100

101

102
    /// <summary>
103
    /// Sets the base URI address used when sending requests.
104
    /// </summary>
105
    /// <param name="path">The path.</param>
106
    /// <returns>A fluent request builder.</returns>
107
    /// <exception cref="ArgumentNullException"><paramref name="path" /> is <see langword="null" />.</exception>
108
    public TBuilder BaseUri(Uri path)
109
    {
110
        if (path is null)
11!
111
            throw new ArgumentNullException(nameof(path));
×
112

113
        var urlBuilder = new UrlBuilder(path);
11✔
114
        RequestMessage.SetUrlBuilder(urlBuilder);
11✔
115

116
        RequestMessage.Synchronize();
11✔
117

118

119
        return (TBuilder)this;
11✔
120
    }
121

122
    /// <summary>
123
    /// Sets the base URI address used when sending requests.
124
    /// </summary>
125
    /// <param name="path">The path.</param>
126
    /// <returns>A fluent request builder.</returns>
127
    /// <exception cref="ArgumentNullException"><paramref name="path" /> is <see langword="null" />.</exception>
128
    public TBuilder BaseUri(string path)
129
    {
130
        if (path is null)
10!
131
            throw new ArgumentNullException(nameof(path));
×
132

133
        var uri = new Uri(path, UriKind.Absolute);
10✔
134
        return BaseUri(uri);
10✔
135
    }
136

137

138
    /// <summary>
139
    /// Sets the base URI from the specified <paramref name="path"/>.
140
    /// </summary>
141
    /// <param name="path">The full Uri path.</param>
142
    /// <returns>A fluent request builder.</returns>
143
    /// <exception cref="ArgumentNullException"><paramref name="path" /> is <see langword="null" />.</exception>
144
    public TBuilder FullUri(Uri path)
145
    {
146
        if (path is null)
×
147
            throw new ArgumentNullException(nameof(path));
×
148

149
        return BaseUri(path);
×
150
    }
151

152
    /// <summary>
153
    /// Sets the base URI from the specified <paramref name="path"/>.
154
    /// </summary>
155
    /// <param name="path">The full Uri path.</param>
156
    /// <returns>A fluent request builder.</returns>
157
    /// <exception cref="ArgumentNullException"><paramref name="path" /> is <see langword="null" />.</exception>
158
    public TBuilder FullUri(string path)
159
    {
160
        if (path is null)
1!
161
            throw new ArgumentNullException(nameof(path));
×
162

163
        var u = new Uri(path, UriKind.Absolute);
1✔
164
        return BaseUri(u);
1✔
165
    }
166

167

168
    /// <summary>
169
    /// Appends the specified <paramref name="path"/> to the BaseUri of the request.
170
    /// </summary>
171
    /// <param name="path">The path to append.</param>
172
    /// <returns>A fluent request builder.</returns>
173
    public TBuilder AppendPath(Uri? path)
174
    {
175
        if (path is null)
×
176
            return (TBuilder)this;
×
177

178
        var urlBuilder = RequestMessage.GetUrlBuilder();
×
179
        urlBuilder.AppendPath(path);
×
180

181
        RequestMessage.Synchronize();
×
182

183
        return (TBuilder)this;
×
184
    }
185

186
    /// <summary>
187
    /// Appends the specified <paramref name="path" /> to the BaseUri of the request.
188
    /// </summary>
189
    /// <param name="path">The path to append.</param>
190
    /// <returns>
191
    /// A fluent request builder.
192
    /// </returns>
193
    public TBuilder AppendPath(string? path)
194
    {
195
        if (path is null)
76!
196
            return (TBuilder)this;
×
197

198
        var urlBuilder = RequestMessage.GetUrlBuilder();
76✔
199
        urlBuilder.AppendPath(path);
76✔
200

201
        RequestMessage.Synchronize();
76✔
202

203
        return (TBuilder)this;
76✔
204
    }
205

206
    /// <summary>
207
    /// Appends the specified <paramref name="path" /> to the BaseUri of the request.
208
    /// </summary>
209
    /// <typeparam name="TValue">The type of the value.</typeparam>
210
    /// <param name="path">The path to append.</param>
211
    /// <returns>A fluent request builder.</returns>
212
    public TBuilder AppendPath<TValue>(TValue? path)
213
    {
214
        if (path is null)
×
215
            return (TBuilder)this;
×
216

217
        var urlBuilder = RequestMessage.GetUrlBuilder();
×
218
        urlBuilder.AppendPath(path);
×
219

220
        RequestMessage.Synchronize();
×
221

222
        return (TBuilder)this;
×
223
    }
224

225
    /// <summary>
226
    /// Appends the specified <paramref name="paths"/> to the BaseUri of the request.
227
    /// </summary>
228
    /// <param name="paths">The paths to append.</param>
229
    /// <returns>A fluent request builder.</returns>
230
    public TBuilder AppendPaths(IEnumerable<string>? paths)
231
    {
232
        if (paths is null)
1!
233
            return (TBuilder)this;
×
234

235
        var urlBuilder = RequestMessage.GetUrlBuilder();
1✔
236
        urlBuilder.AppendPaths(paths);
1✔
237

238
        RequestMessage.Synchronize();
1✔
239

240
        return (TBuilder)this;
1✔
241
    }
242

243
    /// <summary>
244
    /// Appends the specified <paramref name="paths"/> to the BaseUri of the request.
245
    /// </summary>
246
    /// <param name="paths">The paths to append.</param>
247
    /// <returns>A fluent request builder.</returns>
248
    public TBuilder AppendPaths(params string[]? paths)
249
    {
250
        if (paths is null)
1!
251
            return (TBuilder)this;
×
252

253
        var urlBuilder = RequestMessage.GetUrlBuilder();
1✔
254
        urlBuilder.AppendPaths(paths);
1✔
255

256
        RequestMessage.Synchronize();
1✔
257

258
        return (TBuilder)this;
1✔
259
    }
260

261
    /// <summary>
262
    /// Appends the specified <paramref name="path" /> to the BaseUri of the request.
263
    /// </summary>
264
    /// <param name="condition">If condition is true, append path will be added; otherwise ignore path.</param>
265
    /// <param name="path">The path to append.</param>
266
    /// <returns>
267
    /// A fluent request builder.
268
    /// </returns>
269
    public TBuilder AppendPathIf(Func<bool> condition, string? path)
270
    {
271
        if (path is null)
×
272
            return (TBuilder)this;
×
273

274
        if (condition is null || !condition())
×
275
            return (TBuilder)this;
×
276

277
        return AppendPath(path);
×
278
    }
279

280
    /// <summary>
281
    /// Appends the specified <paramref name="path" /> to the BaseUri of the request.
282
    /// </summary>
283
    /// <param name="condition">If condition is true, append path will be added; otherwise ignore path.</param>
284
    /// <param name="path">The path to append.</param>
285
    /// <returns>
286
    /// A fluent request builder.
287
    /// </returns>
288
    public TBuilder AppendPathIf(bool condition, string? path)
289
    {
290
        if (path is null)
×
291
            return (TBuilder)this;
×
292

293
        if (!condition)
×
294
            return (TBuilder)this;
×
295

296
        return AppendPath(path);
×
297
    }
298

299
    /// <summary>
300
    /// Appends the specified <paramref name="path" /> to the BaseUri of the request.
301
    /// </summary>
302
    /// <typeparam name="TValue">The type of the value.</typeparam>
303
    /// <param name="condition">If condition is true, append path will be added; otherwise ignore path.</param>
304
    /// <param name="path">The path to append.</param>
305
    /// <returns>A fluent request builder.</returns>
306
    public TBuilder AppendPathIf<TValue>(Func<bool> condition, TValue? path)
307
    {
308
        if (path is null)
×
309
            return (TBuilder)this;
×
310

311
        if (condition is null || !condition())
×
312
            return (TBuilder)this;
×
313

314
        return AppendPath(path);
×
315
    }
316

317
    /// <summary>
318
    /// Appends the specified <paramref name="path" /> to the BaseUri of the request.
319
    /// </summary>
320
    /// <typeparam name="TValue">The type of the value.</typeparam>
321
    /// <param name="condition">If condition is true, append path will be added; otherwise ignore path.</param>
322
    /// <param name="path">The path to append.</param>
323
    /// <returns>A fluent request builder.</returns>
324
    public TBuilder AppendPathIf<TValue>(bool condition, TValue? path)
325
    {
326
        if (path is null)
×
327
            return (TBuilder)this;
×
328

329
        if (!condition)
×
330
            return (TBuilder)this;
×
331

332
        return AppendPath(path);
×
333
    }
334

335

336
    /// <summary>
337
    /// Appends the specified <paramref name="name"/> and <paramref name="value"/> to the request Uri.
338
    /// </summary>
339
    /// <param name="name">The query parameter name.</param>
340
    /// <param name="value">The query parameter value.</param>
341
    /// <returns>A fluent request builder.</returns>
342
    /// <exception cref="ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
343
    public TBuilder QueryString(string name, string? value)
344
    {
345
        if (name is null)
42!
346
            throw new ArgumentNullException(nameof(name));
×
347

348

349
        var urlBuilder = RequestMessage.GetUrlBuilder();
42✔
350
        urlBuilder.AppendQuery(name, value);
42✔
351

352
        RequestMessage.Synchronize();
42✔
353

354
        return (TBuilder)this;
42✔
355

356
    }
357

358
    /// <summary>
359
    /// Appends the specified <paramref name="name" /> and <paramref name="value" /> to the request Uri.
360
    /// </summary>
361
    /// <typeparam name="TValue">The type of the value.</typeparam>
362
    /// <param name="name">The query parameter name.</param>
363
    /// <param name="value">The query parameter value.</param>
364
    /// <returns>
365
    /// A fluent request builder.
366
    /// </returns>
367
    /// <exception cref="System.ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
368
    public TBuilder QueryString<TValue>(string name, TValue? value)
369
    {
370
        if (name is null)
39!
371
            throw new ArgumentNullException(nameof(name));
×
372

373
        var v = value switch
39!
374
        {
39✔
375
            DateTime dateTime => dateTime.ToString("o"),
1✔
NEW
376
            DateTimeOffset dateTimeOffset => dateTimeOffset.ToString("o"),
×
377
#if NET6_0_OR_GREATER
39✔
NEW
378
            DateOnly dateOnly => dateOnly.ToString("o"),
×
379
#endif
39✔
380
            _ => value?.ToString()
38!
381
        };
39✔
382

383
        return QueryString(name, v);
39✔
384
    }
385

386
    /// <summary>
387
    /// Appends the specified <paramref name="name" /> and <paramref name="values" /> to the request Uri.
388
    /// </summary>
389
    /// <typeparam name="TValue">The type of the value.</typeparam>
390
    /// <param name="name">The query parameter name.</param>
391
    /// <param name="values">The query parameter values.</param>
392
    /// <returns>
393
    /// A fluent request builder.
394
    /// </returns>
395
    /// <exception cref="System.ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
396
    public TBuilder QueryStrings<TValue>(string name, IEnumerable<TValue>? values)
397
    {
398
        if (name is null)
1!
399
            throw new ArgumentNullException(nameof(name));
×
400

401
        if (values is null)
1!
402
            return (TBuilder)this;
×
403

404
        foreach (var value in values)
6✔
405
            QueryString(name, value);
2✔
406

407
        return (TBuilder)this;
1✔
408
    }
409

410

411
    /// <summary>
412
    /// Appends the specified <paramref name="name"/> and <paramref name="value"/> to the request Uri if the specified <paramref name="condition"/> is true.
413
    /// </summary>
414
    /// <param name="condition">If condition is true, query string will be added; otherwise ignore query string.</param>
415
    /// <param name="name">The query parameter name.</param>
416
    /// <param name="value">The query parameter value.</param>
417
    /// <returns>A fluent request builder.</returns>
418
    /// <exception cref="ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
419
    public TBuilder QueryStringIf(Func<bool> condition, string name, string? value)
420
    {
421
        if (condition is null || !condition())
×
422
            return (TBuilder)this;
×
423

424
        return QueryString(name, value);
×
425
    }
426

427
    /// <summary>
428
    /// Appends the specified <paramref name="name"/> and <paramref name="value"/> to the request Uri if the specified <paramref name="condition"/> is true.
429
    /// </summary>
430
    /// <param name="condition">If condition is true, query string will be added; otherwise ignore query string.</param>
431
    /// <param name="name">The query parameter name.</param>
432
    /// <param name="value">The query parameter value.</param>
433
    /// <returns>A fluent request builder.</returns>
434
    /// <exception cref="ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
435
    public TBuilder QueryStringIf(bool condition, string name, string? value)
436
    {
437
        if (!condition)
×
438
            return (TBuilder)this;
×
439

440
        return QueryString(name, value);
×
441
    }
442

443
    /// <summary>
444
    /// Appends the specified <paramref name="name" /> and <paramref name="value" /> to the request Uri if the specified <paramref name="condition" /> is true.
445
    /// </summary>
446
    /// <typeparam name="TValue">The type of the value.</typeparam>
447
    /// <param name="condition">If condition is true, query string will be added; otherwise ignore query string.</param>
448
    /// <param name="name">The query parameter name.</param>
449
    /// <param name="value">The query parameter value.</param>
450
    /// <returns>
451
    /// A fluent request builder.
452
    /// </returns>
453
    /// <exception cref="System.ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
454
    public TBuilder QueryStringIf<TValue>(Func<bool> condition, string name, TValue? value)
455
    {
456
        if (condition is null || !condition())
×
457
            return (TBuilder)this;
×
458

459
        return QueryString(name, value);
×
460
    }
461

462
    /// <summary>
463
    /// Appends the specified <paramref name="name" /> and <paramref name="value" /> to the request Uri if the specified <paramref name="condition" /> is true.
464
    /// </summary>
465
    /// <typeparam name="TValue">The type of the value.</typeparam>
466
    /// <param name="condition">If condition is true, query string will be added; otherwise ignore query string.</param>
467
    /// <param name="name">The query parameter name.</param>
468
    /// <param name="value">The query parameter value.</param>
469
    /// <returns>
470
    /// A fluent request builder.
471
    /// </returns>
472
    /// <exception cref="System.ArgumentNullException"><paramref name="name" /> is <see langword="null" />.</exception>
473
    public TBuilder QueryStringIf<TValue>(bool condition, string name, TValue? value)
474
    {
475
        if (!condition)
×
476
            return (TBuilder)this;
×
477

478
        return QueryString(name, value);
×
479
    }
480
}
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

© 2025 Coveralls, Inc