Skip to content

Commit 09374d9

Browse files
author
Michael Ushakov
committed
Merge branch 'release/1.6.0'
2 parents 7c88ead + 8b31bcb commit 09374d9

File tree

6 files changed

+66
-24
lines changed

6 files changed

+66
-24
lines changed

README.md

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Key concepts:
3232
- `GET /api/[controller]/?[page={page}&size={size}&sort={sort}&order={order}]` to get `PagedDataDto<T>`
3333
now we also have possibility to send **ANY number of query params**, you just have to pass filter func to `EfModelManager` or do it in your own way like in [WeatherControl example with edgedb](https://github.com/Wissance/WeatherControl/blob/master/WeatherControl/Wissance.WeatherControl.WebApi.V2/Helpers/EqlResolver.cs). We also pass sort (column name) && order (`asc` or `desc`) to manager classes,
3434
`EfModelManager` allows to sort **by any column**.
35-
Unfortunately here we have a ***ONE disadvantage*** - **we should override `Swagger` info to show query parameters usage!!!**
35+
<strike> Unfortunately here we have a ***ONE disadvantage*** - **we should override `Swagger` info to show query parameters usage!!!** </strike> Starting from `1.6.0` it is possible to see all parameters in `Swagger` and use them.
3636
- `GET /api/[controller]/{id}` to get one object by `id`
3737
- full `CRUD` controller (`BasicCrudController`) = basic read controller (`BasicReadController`) + `Create`, `Update` and `Delete` operations :
3838
- `POST /api/[controller]` - for new object creation
@@ -119,7 +119,7 @@ public MoidelContext: DbContext<ModelContext>, IModelContext
119119
5. Create `Controller` class and a manager class pair, i.e. consider here full `CRUD`
120120
```csharp
121121
[ApiController]
122-
public class BookController : BasicCrudController<BookDto, BookEntity, int>
122+
public class BookController : BasicCrudController<BookDto, BookEntity, int, EmptyAdditionalFilters>
123123
{
124124
public BookController(BookManager manager)
125125
{
@@ -130,7 +130,7 @@ public class BookController : BasicCrudController<BookDto, BookEntity, int>
130130
private BookManager _manager;
131131
}
132132

133-
public class BookManager : EfModelManager<BookEntity, BookDto, int>
133+
public class BookManager : EfModelManager<BookEntity, BookDto, int, EmptyAdditionalFilters>
134134
{
135135
public BookManager(ModelContext modelContext, ILoggerFactory loggerFactory) : base(modelContext, BookFactory.Create, loggerFactory)
136136
{
@@ -150,6 +150,34 @@ public class BookManager : EfModelManager<BookEntity, BookDto, int>
150150
private readonly ModelContext _modelContext;
151151
}
152152
```
153+
154+
Last generic parameter in above example - `EmptyAdditionalFilters` is a class that holds
155+
additional parameters for search to see in Swagger, just specify a new class implementing
156+
`IReadFilterable` i.e.:
157+
158+
```csharp
159+
public class BooksFilterable : IReadFilterable
160+
{
161+
public IDictionary<string, string> SelectFilters()
162+
{
163+
IDictionary<string, string> additionalFilters = new Dictionary<string, string>();
164+
if (!string.IsNullOrEmpty(Title))
165+
{
166+
additionalFilters.Add(FilterParamsNames.TitleParameter, Title);
167+
}
168+
169+
if (Authors != null && Authors.Length > 0)
170+
{
171+
additionalFilters.Add(FilterParamsNames.AuthorsParameter, string.Join(",", Authors));
172+
}
173+
174+
return additionalFilters;
175+
}
176+
177+
[FromQuery(Name = "title")] public string Title { get; set; }
178+
[FromQuery(Name = "author")] public string[] Authors { get; set; }
179+
}
180+
```
153181

154182
### 5. Nuget package
155183
You could find nuget-package [here](https://www.nuget.org/packages/Wissance.WebApiToolkit)
@@ -159,7 +187,7 @@ You could find nuget-package [here](https://www.nuget.org/packages/Wissance.WebA
159187

160188
```csharp
161189
[ApiController]
162-
public class StationController : BasicCrudController<StationDto, StationEntity, int>
190+
public class StationController : BasicCrudController<StationDto, StationEntity, int, EmptyAdditionalFilters>
163191
{
164192
public StationController(StationManager manager)
165193
{

Wissance.WebApiToolkit/Wissance.WebApiToolkit/Controllers/BasicBulkCrudController.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
using System.Threading.Tasks;
22
using Microsoft.AspNetCore.Mvc;
3+
using Wissance.WebApiToolkit.Data;
34
using Wissance.WebApiToolkit.Dto;
45

56
namespace Wissance.WebApiToolkit.Controllers
67
{
7-
public class BasicBulkCrudController<TRes, TData, TId> : BasicReadController<TRes, TData, TId>
8+
public class BasicBulkCrudController<TRes, TData, TId, TFilter> : BasicReadController<TRes, TData, TId, TFilter>
89
where TRes : class
10+
where TFilter: class, IReadFilterable
911
{
1012
[HttpPost]
1113
[Route("api/bulk/[controller]")]

Wissance.WebApiToolkit/Wissance.WebApiToolkit/Controllers/BasicCrudController.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
using System.Collections.Generic;
33
using System.Threading.Tasks;
44
using Microsoft.AspNetCore.Mvc;
5+
using Wissance.WebApiToolkit.Data;
56
using Wissance.WebApiToolkit.Dto;
67

78
namespace Wissance.WebApiToolkit.Controllers
89
{
9-
public abstract class BasicCrudController <TRes, TData, TId> : BasicReadController<TRes, TData, TId>
10+
public abstract class BasicCrudController <TRes, TData, TId, TFilter> : BasicReadController<TRes, TData, TId, TFilter>
1011
where TRes : class
12+
where TFilter: class, IReadFilterable
1113
{
1214
[HttpPost]
1315
[Route("api/[controller]")]

Wissance.WebApiToolkit/Wissance.WebApiToolkit/Controllers/BasicReadController.cs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,22 @@
1313
namespace Wissance.WebApiToolkit.Controllers
1414
{
1515

16-
public abstract class BasicReadController<TRes, TData, TId> : BasicPagedDataController
16+
public abstract class BasicReadController<TRes, TData, TId, TFilter> : BasicPagedDataController
1717
where TRes: class
18+
where TFilter: class, IReadFilterable
1819
{
1920
[HttpGet]
2021
[Route("api/[controller]")]
2122
public virtual async Task<PagedDataDto<TRes>> ReadAsync([FromQuery] int? page, [FromQuery] int? size, [FromQuery] string sort,
22-
[FromQuery] string order)
23+
[FromQuery] string order, TFilter additionalFilters = null)
2324
{
2425
int pageNumber = GetPage(page);
2526
int pageSize = GetPageSize(size);
2627
SortOption sorting = !string.IsNullOrEmpty(sort) ? new SortOption(sort, order) : null;
27-
string queryStrValue = HttpContext.Request.QueryString.Value;
28-
IDictionary<string, StringValues> queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(queryStrValue);
29-
IDictionary<string, string> parameters = queryDictionary.Where(kv => _paramsToOmit.All(p => !string.Equals(p, kv.Key.ToLower())))
30-
.ToDictionary(k => k.Key, v => v.Value.ToString());
31-
OperationResultDto<Tuple<IList<TRes>, long>> result = await Manager.GetAsync(pageNumber, pageSize, sorting, parameters);
28+
IDictionary<string, string> additionalQueryParams = additionalFilters != null
29+
? additionalFilters.SelectFilters()
30+
: new Dictionary<string, string>();
31+
OperationResultDto<Tuple<IList<TRes>, long>> result = await Manager.GetAsync(pageNumber, pageSize, sorting, additionalQueryParams);
3232
HttpContext.Response.StatusCode = result.Status;
3333
return new PagedDataDto<TRes>(pageNumber, result.Data.Item2, PagingUtils.GetTotalPages(result.Data.Item2, pageSize), result.Data.Item1);
3434
}
@@ -41,17 +41,6 @@ public async Task<TRes> ReadByIdAsync([FromRoute] TId id)
4141
HttpContext.Response.StatusCode = result.Status;
4242
return result.Data;
4343
}
44-
45-
private const string PageQueryParam = "page";
46-
private const string SizeQueryParam = "size";
47-
private const string SortQueryParam = "sort";
48-
private const string OrderQueryParam = "order";
49-
50-
private readonly IList<string> _paramsToOmit = new List<string>()
51-
{
52-
PageQueryParam, SizeQueryParam, SortQueryParam, OrderQueryParam
53-
};
54-
5544
public IModelManager<TRes, TData, TId> Manager { get; set; }
5645
}
5746
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Collections.Generic;
2+
3+
namespace Wissance.WebApiToolkit.Data
4+
{
5+
public class EmptyAdditionalFilters : IReadFilterable
6+
{
7+
public IDictionary<string, string> SelectFilters()
8+
{
9+
return new Dictionary<string, string>();
10+
}
11+
}
12+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Collections.Generic;
2+
3+
namespace Wissance.WebApiToolkit.Data
4+
{
5+
public interface IReadFilterable
6+
{
7+
IDictionary<string, string> SelectFilters();
8+
}
9+
}

0 commit comments

Comments
 (0)