Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0c7de45

Browse files
author
Bart Koelman
committed
Updated to .NET Core 3.1 with JsonApiDotNetCore v4.0
1 parent 805a773 commit 0c7de45

File tree

14 files changed

+259
-244
lines changed

14 files changed

+259
-244
lines changed

src/Example.Api/Controllers/BooksController.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
using Example.Api.Resources;
2+
using JsonApiDotNetCore.Configuration;
23
using JsonApiDotNetCore.Controllers;
34
using JsonApiDotNetCore.Services;
5+
using Microsoft.Extensions.Logging;
46

57
namespace Example.Api.Controllers
68
{
79
public class BooksController : JsonApiController<Book>
810
{
9-
public BooksController(IJsonApiContext jsonApiContext, IResourceService<Book> resourceService)
10-
: base(jsonApiContext, resourceService)
11+
public BooksController(IJsonApiOptions options, ILoggerFactory loggerFactory,
12+
IResourceService<Book> resourceService)
13+
: base(options, loggerFactory, resourceService)
1114
{
1215
}
1316
}

src/Example.Api/Controllers/PeopleController.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
using Example.Api.Resources;
2+
using JsonApiDotNetCore.Configuration;
23
using JsonApiDotNetCore.Controllers;
34
using JsonApiDotNetCore.Services;
5+
using Microsoft.Extensions.Logging;
46

57
namespace Example.Api.Controllers
68
{
79
public class PeopleController : JsonApiController<Person>
810
{
9-
public PeopleController(IJsonApiContext jsonApiContext, IResourceService<Person> resourceService)
10-
: base(jsonApiContext, resourceService)
11+
public PeopleController(IJsonApiOptions options, ILoggerFactory loggerFactory,
12+
IResourceService<Person> resourceService)
13+
: base(options, loggerFactory, resourceService)
1114
{
1215
}
1316
}
Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,38 @@
1-
using System.Collections.Generic;
1+
using System.ComponentModel;
22
using System.Linq;
33
using Example.Api.Resources;
4-
using JsonApiDotNetCore.Internal;
5-
using JsonApiDotNetCore.Internal.Query;
6-
using JsonApiDotNetCore.Models;
4+
using JsonApiDotNetCore.Configuration;
5+
using JsonApiDotNetCore.Queries.Expressions;
6+
using JsonApiDotNetCore.Resources;
77

88
namespace Example.Api.Definitions
99
{
10-
public class BookDefinition : ResourceDefinition<Book>
10+
public class BookDefinition : JsonApiResourceDefinition<Book>
1111
{
1212
private readonly IResourceGraph _resourceGraph;
1313

1414
public BookDefinition(IResourceGraph resourceGraph)
15+
: base(resourceGraph)
1516
{
1617
_resourceGraph = resourceGraph;
1718
}
1819

19-
protected override PropertySortOrder GetDefaultSortOrder()
20+
public override SortExpression OnApplySort(SortExpression existingSort)
2021
{
21-
return new PropertySortOrder
22+
if (existingSort != null)
2223
{
23-
(book => book.Id, SortDirection.Ascending)
24-
};
24+
return existingSort;
25+
}
26+
27+
return CreateSortExpressionFromLambda(new PropertySortOrder
28+
{
29+
(book => book.Id, ListSortDirection.Ascending)
30+
});
2531
}
2632

27-
public override QueryFilters GetQueryFilters()
33+
public override QueryStringParameterHandlers<Book> OnRegisterQueryableHandlersForQueryStringParameters()
2834
{
29-
return new QueryFilters
35+
return new QueryStringParameterHandlers<Book>
3036
{
3137
{"hide", (bookQuery, parameterValue) => GetBooksFilter(bookQuery, parameterValue)}
3238
};
@@ -37,15 +43,21 @@ private IQueryable<Book> GetBooksFilter(IQueryable<Book> bookQuery, string param
3743
return parameterValue == "all" ? bookQuery.Where(_ => false) : bookQuery;
3844
}
3945

40-
protected override List<AttrAttribute> OutputAttrs(Book instance)
46+
public override SparseFieldSetExpression OnApplySparseFieldSet(SparseFieldSetExpression existingSparseFieldSet)
4147
{
42-
var contextEntity = _resourceGraph.GetContextEntity(typeof(Book));
48+
if (existingSparseFieldSet != null)
49+
{
50+
var visibleFields = existingSparseFieldSet.Fields
51+
.Where(field => !field.Property.Name.StartsWith("Hidden"))
52+
.ToList();
4353

44-
var visibleAttributes = contextEntity.Attributes
45-
.Where(attr => !attr.InternalAttributeName.StartsWith("Hidden"))
46-
.ToList();
54+
if (visibleFields.Any())
55+
{
56+
return new SparseFieldSetExpression(visibleFields);
57+
}
58+
}
4759

48-
return visibleAttributes;
60+
return null;
4961
}
5062
}
5163
}

src/Example.Api/Example.Api.csproj

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22
<PropertyGroup>
3-
<TargetFramework>netcoreapp2.1</TargetFramework>
3+
<TargetFramework>netcoreapp3.1</TargetFramework>
44
</PropertyGroup>
55

66
<ItemGroup>
7-
<PackageReference Include="JsonApiDotNetCore" Version="3.1.0" />
8-
<PackageReference Include="Microsoft.AspNetCore.App" />
9-
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
10-
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.14" />
11-
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.1.1" />
7+
<PackageReference Include="JsonApiDotNetCore" Version="4.0.0" />
8+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.10" />
9+
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" />
1210
</ItemGroup>
1311
</Project>

src/Example.Api/Program.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
using Microsoft.AspNetCore;
2-
using Microsoft.AspNetCore.Hosting;
1+
using Microsoft.AspNetCore.Hosting;
2+
using Microsoft.Extensions.Hosting;
33

44
namespace Example.Api
55
{
66
public class Program
77
{
88
public static void Main(string[] args)
99
{
10-
CreateWebHostBuilder(args).Build().Run();
10+
CreateHostBuilder(args).Build().Run();
1111
}
1212

13-
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
13+
public static IHostBuilder CreateHostBuilder(string[] args)
1414
{
15-
return WebHost.CreateDefaultBuilder(args)
16-
.UseStartup<Startup>();
15+
return Host.CreateDefaultBuilder(args)
16+
.ConfigureWebHostDefaults(webBuilder =>
17+
{
18+
webBuilder.UseStartup<Startup>();
19+
});
1720
}
1821
}
1922
}
Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
1-
using System.Linq;
1+
using System.Collections.Generic;
2+
using System.Linq;
23
using Example.Api.Resources;
3-
using JsonApiDotNetCore.Data;
4-
using JsonApiDotNetCore.Models;
5-
using JsonApiDotNetCore.Services;
4+
using JsonApiDotNetCore.Configuration;
5+
using JsonApiDotNetCore.Queries;
6+
using JsonApiDotNetCore.Repositories;
7+
using JsonApiDotNetCore.Resources;
68
using Microsoft.Extensions.Logging;
79

810
namespace Example.Api.Repositories
911
{
10-
public class PersonRepository : DefaultEntityRepository<Person>
12+
public class PersonRepository : EntityFrameworkCoreRepository<Person>
1113
{
1214
private readonly ILogger<PersonRepository> _logger;
1315

14-
public PersonRepository(ILoggerFactory loggerFactory, IJsonApiContext jsonApiContext,
15-
IDbContextResolver contextResolver, ResourceDefinition<Person> resourceDefinition = null)
16-
: base(loggerFactory, jsonApiContext, contextResolver, resourceDefinition)
16+
public PersonRepository(ITargetedFields targetedFields, IDbContextResolver contextResolver,
17+
IResourceGraph resourceGraph, IResourceFactory resourceFactory,
18+
IEnumerable<IQueryConstraintProvider> constraintProviders, ILoggerFactory loggerFactory)
19+
: base(targetedFields, contextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory)
1720
{
1821
_logger = loggerFactory.CreateLogger<PersonRepository>();
1922
}
2023

21-
public override IQueryable<Person> Get()
24+
protected override IQueryable<Person> GetAll()
2225
{
23-
_logger.LogDebug("Entering PersonRepository.Get");
26+
_logger.LogDebug("Entering PersonRepository.GetAll");
2427

25-
return base.Get();
28+
return base.GetAll();
2629
}
2730
}
2831
}

src/Example.Api/Resources/Book.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.ComponentModel.DataAnnotations;
2-
using JsonApiDotNetCore.Models;
2+
using JsonApiDotNetCore.Resources;
3+
using JsonApiDotNetCore.Resources.Annotations;
34

45
namespace Example.Api.Resources
56
{
@@ -9,7 +10,7 @@ public class Book : Identifiable
910
[Required]
1011
public string Title { get; set; }
1112

12-
[Attr("synopsis", isImmutable: true, isSortable: false)]
13+
[Attr(PublicName = "synopsis", Capabilities = AttrCapabilities.AllowView | AttrCapabilities.AllowFilter)]
1314
[MinLength(3)]
1415
public string Summary { get; set; }
1516

src/Example.Api/Resources/Person.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
using System;
22
using System.Collections.Generic;
33
using System.ComponentModel.DataAnnotations;
4-
using JsonApiDotNetCore.Models;
4+
using JsonApiDotNetCore.Resources;
5+
using JsonApiDotNetCore.Resources.Annotations;
56

67
namespace Example.Api.Resources
78
{
@@ -14,7 +15,7 @@ public class Person : Identifiable
1415
[Required]
1516
public string LastName { get; set; }
1617

17-
[Attr(isFilterable: false)]
18+
[Attr(Capabilities = ~AttrCapabilities.AllowFilter)]
1819
public DateTimeOffset BornAt { get; set; }
1920

2021
[HasMany]
Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,37 @@
11
using System.Collections.Generic;
2+
using System.Threading;
23
using System.Threading.Tasks;
34
using Example.Api.Resources;
4-
using JsonApiDotNetCore.Data;
5+
using JsonApiDotNetCore.Configuration;
6+
using JsonApiDotNetCore.Hooks;
7+
using JsonApiDotNetCore.Middleware;
8+
using JsonApiDotNetCore.Queries;
9+
using JsonApiDotNetCore.Repositories;
10+
using JsonApiDotNetCore.Resources;
511
using JsonApiDotNetCore.Services;
612
using Microsoft.Extensions.Logging;
713

814
namespace Example.Api.Services
915
{
10-
public class BookService : EntityResourceService<Book>
16+
public class BookService : JsonApiResourceService<Book>
1117
{
1218
private readonly ILogger<BookService> _logger;
1319

14-
public BookService(IJsonApiContext jsonApiContext, IEntityRepository<Book> entityRepository,
15-
ILoggerFactory loggerFactory = null)
16-
: base(jsonApiContext, entityRepository, loggerFactory)
20+
public BookService(IResourceRepositoryAccessor repositoryAccessor, IQueryLayerComposer queryLayerComposer,
21+
IPaginationContext paginationContext, IJsonApiOptions options, ILoggerFactory loggerFactory,
22+
IJsonApiRequest request, IResourceChangeTracker<Book> resourceChangeTracker,
23+
IResourceHookExecutorFacade hookExecutor)
24+
: base(repositoryAccessor, queryLayerComposer, paginationContext, options, loggerFactory, request,
25+
resourceChangeTracker, hookExecutor)
1726
{
1827
_logger = loggerFactory.CreateLogger<BookService>();
1928
}
2029

21-
public override async Task<IEnumerable<Book>> GetAsync()
30+
public override async Task<IReadOnlyCollection<Book>> GetAsync(CancellationToken cancellationToken)
2231
{
2332
_logger.LogDebug("Entering BookService.GetAsync");
2433

25-
return await base.GetAsync();
34+
return await base.GetAsync(cancellationToken);
2635
}
2736
}
2837
}

src/Example.Api/Startup.cs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@
44
using Example.Api.Repositories;
55
using Example.Api.Resources;
66
using Example.Api.Services;
7-
using JsonApiDotNetCore.Data;
8-
using JsonApiDotNetCore.Extensions;
9-
using JsonApiDotNetCore.Models;
10-
using JsonApiDotNetCore.Services;
7+
using JsonApiDotNetCore.Configuration;
8+
using JsonApiDotNetCore.Resources;
9+
using JsonApiDotNetCore.Resources.Annotations;
1110
using Microsoft.AspNetCore.Builder;
1211
using Microsoft.AspNetCore.Hosting;
1312
using Microsoft.EntityFrameworkCore;
1413
using Microsoft.Extensions.DependencyInjection;
14+
using Microsoft.Extensions.Hosting;
1515
using Newtonsoft.Json;
16+
using Newtonsoft.Json.Serialization;
1617

1718
namespace Example.Api
1819
{
@@ -31,29 +32,39 @@ public void ConfigureServices(IServiceCollection services)
3132

3233
services.AddJsonApi<AppDbContext>(options =>
3334
{
34-
options.IncludeTotalRecordCount = true;
35+
options.IncludeTotalResourceCount = true;
3536
options.Namespace = "api";
36-
options.RelativeLinks = true;
37+
options.UseRelativeLinks = true;
3738
options.SerializerSettings.Formatting = Formatting.Indented;
38-
options.DefaultPageSize = 10;
39+
options.DefaultPageSize = new PageSize(10);
40+
options.EnableLegacyFilterNotation = true;
41+
options.TopLevelLinks = LinkTypes.Paging;
42+
options.ResourceLinks = LinkTypes.None;
43+
44+
options.SerializerSettings.ContractResolver = new DefaultContractResolver
45+
{
46+
NamingStrategy = new KebabCaseNamingStrategy()
47+
};
3948
});
4049

41-
services.AddScoped<IEntityRepository<Person>, PersonRepository>();
42-
services.AddScoped<IResourceService<Book>, BookService>();
43-
services.AddScoped<ResourceDefinition<Book>, BookDefinition>();
50+
services.AddResourceRepository<PersonRepository>();
51+
services.AddResourceService<BookService>();
52+
services.AddScoped<IResourceDefinition<Book>, BookDefinition>();
4453
}
4554

4655
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
47-
public void Configure(IApplicationBuilder app, IHostingEnvironment env, AppDbContext appDbContext)
56+
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment, AppDbContext appDbContext)
4857
{
4958
SeedSampleData(appDbContext);
5059

51-
if (env.IsDevelopment())
60+
if (environment.IsDevelopment())
5261
{
5362
app.UseDeveloperExceptionPage();
5463
}
5564

65+
app.UseRouting();
5666
app.UseJsonApi();
67+
app.UseEndpoints(endpoints => endpoints.MapControllers());
5768
}
5869

5970
private static void SeedSampleData(AppDbContext appDbContext)

0 commit comments

Comments
 (0)