Skip to content

Redesign conversion between JSON objects and ASP.NET models #1091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 49 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
8534c41
Replaced suppression with fix
Sep 20, 2021
f502628
Fixed: do not duplicate the list of JSON:API errors in meta stack tra…
Sep 20, 2021
afe119d
Breaking: Added option to write request body in meta when unable to r…
Sep 20, 2021
2b47438
Breaking: Added option to allow unknown attribute/relationship keys i…
Sep 22, 2021
2b1c32b
Fixed invalid test
Sep 23, 2021
0192e39
Rewrite of reading the request body and converting it into models.
Sep 29, 2021
d247ba2
Updated error message for unknown attribute/relationship
Sep 29, 2021
8dbafd2
Updated error message for unknown resource type
Sep 29, 2021
d243dc3
Unified error messages about the absense or presense of 'id' and 'lid'
Sep 29, 2021
4c3bf71
Unified error messages about the absense of 'type'
Sep 29, 2021
1700c00
Unified error messages about incompatible types
Sep 29, 2021
d4549e8
Revert the use of different exception, because this way the request b…
Sep 29, 2021
c2e31d3
Unified error messages about mismatches in 'id' and 'lid' values
Sep 29, 2021
5ea961f
Additional unification of error messages
Sep 29, 2021
6244ef7
Unified error messages for failed type conversion
Sep 29, 2021
72f02b0
Fix cibuild
Sep 30, 2021
fe10147
Unified error messages about data presense and its value: null/object…
Sep 30, 2021
2322ac8
Unified remaining error messages
Sep 30, 2021
d254ac9
Sealed types and reduced dependencies
Sep 30, 2021
0923c8b
Fixed broken test on linux
Sep 30, 2021
6e0d287
Adapter renames:
Oct 1, 2021
169acc7
Added missing assertions on request body in error meta
Oct 1, 2021
317f293
Refactorings:
Oct 1, 2021
65b1f03
Enhanced existing tests: Assert on resource type when `included` cont…
Oct 2, 2021
5198265
Fixed the number of resource definition callbacks for sparse fieldsets
Oct 4, 2021
64cc4e2
Refactor: removed OperationContainer.Kind because IJsonApiRequest.Wri…
Oct 4, 2021
1e6d18e
Added test to capture the current behavior to return data:null for vo…
Oct 4, 2021
cab3dc6
Improved tests for includes
Oct 5, 2021
d8510aa
Rewrite of rendering the response body from models
Oct 5, 2021
055b93f
Avoid closure in hot code path to reduce allocations
Oct 6, 2021
a7c6009
Cleanup reader and writer
Oct 6, 2021
428b06b
Removed old code
Oct 6, 2021
05f155e
Fixed: crash in test serializer on assertion failure
Oct 6, 2021
fbdcefb
Removed RequestScopedServiceProvider
Oct 6, 2021
7fcb58e
Use sets for include expressions
Oct 6, 2021
f8d71f2
Fixed: return Content-Length header in HEAD response
Oct 6, 2021
ff763f1
Reorganized JADNC.Serialization namespace
Oct 6, 2021
80fe2b2
Created custom exception for remaining errors
Oct 6, 2021
f6caf3a
Fixed: call ResourceDefinition.OnApplyIncludes for all children, even…
Oct 6, 2021
0efde1b
Renamed ResourceContext to ResourceType and exposed it through relati…
Oct 7, 2021
f7e7da4
Moved logic to build resource graph from DbContext into ResourceGraph…
Oct 8, 2021
3d98057
Opened up ResponseModelAdapter for extensibility
Oct 8, 2021
2e3659f
Check off roadmap entry
Oct 11, 2021
2c4e75c
Review feedback
Oct 20, 2021
7158595
Simplified existing tests
Oct 25, 2021
7c6684f
Added extra test for data:null in relationship
Oct 25, 2021
4a8bfdd
Added test for broken resource linkage
Oct 25, 2021
0f41f85
Ported existing unit tests and changed how included[] is built.
Oct 26, 2021
5dfb6ea
Fixed cibuild
Oct 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Removed RequestScopedServiceProvider
  • Loading branch information
Bart Koelman committed Oct 8, 2021
commit fbdcefb2984db8c0da9d4f5960b3fff062c483c0

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ private void AddMiddlewareLayer()
_services.AddSingleton<IJsonApiRoutingConvention, JsonApiRoutingConvention>();
_services.AddSingleton<IControllerResourceMapping>(sp => sp.GetRequiredService<IJsonApiRoutingConvention>());
_services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
_services.AddSingleton<IRequestScopedServiceProvider, RequestScopedServiceProvider>();
_services.AddScoped<IJsonApiRequest, JsonApiRequest>();
_services.AddScoped<IJsonApiWriter, JsonApiWriter>();
_services.AddScoped<IJsonApiReader, JsonApiReader>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
Expand All @@ -13,18 +14,18 @@ internal sealed class JsonApiModelMetadataProvider : DefaultModelMetadataProvide
private readonly JsonApiValidationFilter _jsonApiValidationFilter;

/// <inheritdoc />
public JsonApiModelMetadataProvider(ICompositeMetadataDetailsProvider detailsProvider, IRequestScopedServiceProvider serviceProvider)
public JsonApiModelMetadataProvider(ICompositeMetadataDetailsProvider detailsProvider, IHttpContextAccessor httpContextAccessor)
: base(detailsProvider)
{
_jsonApiValidationFilter = new JsonApiValidationFilter(serviceProvider);
_jsonApiValidationFilter = new JsonApiValidationFilter(httpContextAccessor);
}

/// <inheritdoc />
public JsonApiModelMetadataProvider(ICompositeMetadataDetailsProvider detailsProvider, IOptions<MvcOptions> optionsAccessor,
IRequestScopedServiceProvider serviceProvider)
IHttpContextAccessor httpContextAccessor)
: base(detailsProvider, optionsAccessor)
{
_jsonApiValidationFilter = new JsonApiValidationFilter(serviceProvider);
_jsonApiValidationFilter = new JsonApiValidationFilter(httpContextAccessor);
}

/// <inheritdoc />
Expand Down
30 changes: 21 additions & 9 deletions src/JsonApiDotNetCore/Configuration/JsonApiValidationFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@ namespace JsonApiDotNetCore.Configuration
/// </summary>
internal sealed class JsonApiValidationFilter : IPropertyValidationFilter
{
private readonly IRequestScopedServiceProvider _serviceProvider;
private readonly IHttpContextAccessor _httpContextAccessor;

public JsonApiValidationFilter(IRequestScopedServiceProvider serviceProvider)
public JsonApiValidationFilter(IHttpContextAccessor httpContextAccessor)
{
ArgumentGuard.NotNull(serviceProvider, nameof(serviceProvider));
ArgumentGuard.NotNull(httpContextAccessor, nameof(httpContextAccessor));

_serviceProvider = serviceProvider;
_httpContextAccessor = httpContextAccessor;
}

/// <inheritdoc />
public bool ShouldValidateEntry(ValidationEntry entry, ValidationEntry parentEntry)
{
var request = _serviceProvider.GetRequiredService<IJsonApiRequest>();
IServiceProvider serviceProvider = GetServiceProvider();

var request = serviceProvider.GetRequiredService<IJsonApiRequest>();

if (IsId(entry.Key))
{
Expand All @@ -39,17 +41,27 @@ public bool ShouldValidateEntry(ValidationEntry entry, ValidationEntry parentEnt
return false;
}

var httpContextAccessor = _serviceProvider.GetRequiredService<IHttpContextAccessor>();

if (httpContextAccessor.HttpContext!.Request.Method == HttpMethods.Patch || request.WriteOperation == WriteOperationKind.UpdateResource)
if (_httpContextAccessor.HttpContext!.Request.Method == HttpMethods.Patch || request.WriteOperation == WriteOperationKind.UpdateResource)
{
var targetedFields = _serviceProvider.GetRequiredService<ITargetedFields>();
var targetedFields = serviceProvider.GetRequiredService<ITargetedFields>();
return IsFieldTargeted(entry, targetedFields);
}

return true;
}

private IServiceProvider GetServiceProvider()
{
HttpContext httpContext = _httpContextAccessor.HttpContext;

if (httpContext == null)
{
throw new InvalidOperationException("Cannot resolve scoped services outside the context of an HTTP request.");
}

return httpContext.RequestServices;
}

private static bool IsId(string key)
{
return key == nameof(Identifiable.Id) || key.EndsWith($".{nameof(Identifiable.Id)}", StringComparison.Ordinal);
Expand Down

This file was deleted.

6 changes: 0 additions & 6 deletions test/UnitTests/Extensions/ServiceCollectionExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ public void RegisterResource_DeviatingDbContextPropertyName_RegistersCorrectly()
services.AddLogging();
services.AddDbContext<TestDbContext>(options => options.UseInMemoryDatabase("UnitTestDb"));

// this is required because the DbContextResolver requires access to the current HttpContext
// to get the request scoped DbContext instance
services.AddScoped<IRequestScopedServiceProvider, TestScopedServiceProvider>();

// Act
services.AddJsonApi<TestDbContext>();

Expand Down Expand Up @@ -171,8 +167,6 @@ public void AddJsonApi_With_Context_Uses_Resource_Type_Name_If_NoOtherSpecified(
services.AddLogging();
services.AddDbContext<TestDbContext>(options => options.UseInMemoryDatabase(Guid.NewGuid().ToString()));

services.AddScoped<IRequestScopedServiceProvider, TestScopedServiceProvider>();

// Act
services.AddJsonApi<TestDbContext>();

Expand Down
35 changes: 0 additions & 35 deletions test/UnitTests/Internal/RequestScopedServiceProviderTests.cs

This file was deleted.

28 changes: 0 additions & 28 deletions test/UnitTests/TestScopedServiceProvider.cs

This file was deleted.