Skip to content

Commit cb3bfab

Browse files
author
Bart Koelman
committed
Merged ErrorDocument and AtomicOperationsDocument into Document
1 parent 766d830 commit cb3bfab

File tree

92 files changed

+507
-589
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+507
-589
lines changed

src/JsonApiDotNetCore/Controllers/CoreJsonApiController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ protected IActionResult Error(IEnumerable<ErrorObject> errors)
2121
{
2222
ArgumentGuard.NotNull(errors, nameof(errors));
2323

24-
var document = new ErrorDocument
24+
var document = new Document
2525
{
2626
Errors = errors.ToList()
2727
};

src/JsonApiDotNetCore/Middleware/AsyncJsonApiExceptionFilter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ public Task OnExceptionAsync(ExceptionContext context)
2626

2727
if (context.HttpContext.IsJsonApiRequest())
2828
{
29-
ErrorDocument errorDocument = _exceptionHandler.HandleException(context.Exception);
29+
Document document = _exceptionHandler.HandleException(context.Exception);
3030

31-
context.Result = new ObjectResult(errorDocument)
31+
context.Result = new ObjectResult(document)
3232
{
33-
StatusCode = (int)errorDocument.GetErrorStatusCode()
33+
StatusCode = (int)document.GetErrorStatusCode()
3434
};
3535
}
3636

src/JsonApiDotNetCore/Middleware/ExceptionHandler.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public ExceptionHandler(ILoggerFactory loggerFactory, IJsonApiOptions options)
2828
_logger = loggerFactory.CreateLogger<ExceptionHandler>();
2929
}
3030

31-
public ErrorDocument HandleException(Exception exception)
31+
public Document HandleException(Exception exception)
3232
{
3333
ArgumentGuard.NotNull(exception, nameof(exception));
3434

@@ -71,7 +71,7 @@ protected virtual string GetLogMessage(Exception exception)
7171
return exception.Message;
7272
}
7373

74-
protected virtual ErrorDocument CreateErrorDocument(Exception exception)
74+
protected virtual Document CreateErrorDocument(Exception exception)
7575
{
7676
ArgumentGuard.NotNull(exception, nameof(exception));
7777

@@ -90,7 +90,7 @@ protected virtual ErrorDocument CreateErrorDocument(Exception exception)
9090
ApplyOptions(error, exception);
9191
}
9292

93-
return new ErrorDocument
93+
return new Document
9494
{
9595
Errors = errors.ToList()
9696
};

src/JsonApiDotNetCore/Middleware/IExceptionHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ namespace JsonApiDotNetCore.Middleware
88
/// </summary>
99
public interface IExceptionHandler
1010
{
11-
ErrorDocument HandleException(Exception exception);
11+
Document HandleException(Exception exception);
1212
}
1313
}

src/JsonApiDotNetCore/Middleware/JsonApiMiddleware.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ private static async Task FlushResponseAsync(HttpResponse httpResponse, JsonSeri
209209
httpResponse.ContentType = HeaderConstants.MediaType;
210210
httpResponse.StatusCode = (int)error.StatusCode;
211211

212-
var errorDocument = new ErrorDocument
212+
var errorDocument = new Document
213213
{
214214
Errors = error.AsList()
215215
};

src/JsonApiDotNetCore/Serialization/AtomicOperationsResponseSerializer.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public string Serialize(object content)
5959
return SerializeOperationsDocument(operations);
6060
}
6161

62-
if (content is ErrorDocument errorDocument)
62+
if (content is Document errorDocument)
6363
{
6464
return SerializeErrorDocument(errorDocument);
6565
}
@@ -69,7 +69,7 @@ public string Serialize(object content)
6969

7070
private string SerializeOperationsDocument(IEnumerable<OperationContainer> operations)
7171
{
72-
var document = new AtomicOperationsDocument
72+
var document = new Document
7373
{
7474
Results = operations.Select(SerializeOperation).ToList(),
7575
Meta = _metaBuilder.Build()
@@ -120,9 +120,9 @@ private AtomicResultObject SerializeOperation(OperationContainer operation)
120120
};
121121
}
122122

123-
private string SerializeErrorDocument(ErrorDocument errorDocument)
123+
private string SerializeErrorDocument(Document document)
124124
{
125-
return SerializeObject(errorDocument, _options.SerializerSettings, serializer =>
125+
return SerializeObject(document, _options.SerializerSettings, serializer =>
126126
{
127127
serializer.ApplyErrorSettings();
128128
});

src/JsonApiDotNetCore/Serialization/IJsonApiDeserializer.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ namespace JsonApiDotNetCore.Serialization
88
public interface IJsonApiDeserializer
99
{
1010
/// <summary>
11-
/// Deserializes JSON into a <see cref="Document" /> or <see cref="AtomicOperationsDocument" /> and constructs resources from
12-
/// <see cref="ExposableData{T}.Data" />.
11+
/// Deserializes JSON into a <see cref="Document" /> and constructs resources from <see cref="ExposableData{TResource}.Data" />.
1312
/// </summary>
1413
/// <param name="body">
1514
/// The JSON to be deserialized.

src/JsonApiDotNetCore/Serialization/JsonApiWriter.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ public async Task WriteAsync(OutputFormatterWriteContext context)
6565
catch (Exception exception)
6666
#pragma warning restore AV1210 // Catch a specific exception instead of Exception, SystemException or ApplicationException
6767
{
68-
ErrorDocument errorDocument = _exceptionHandler.HandleException(exception);
69-
responseContent = _serializer.Serialize(errorDocument);
68+
Document document = _exceptionHandler.HandleException(exception);
69+
responseContent = _serializer.Serialize(document);
7070

71-
response.StatusCode = (int)errorDocument.GetErrorStatusCode();
71+
response.StatusCode = (int)document.GetErrorStatusCode();
7272
}
7373

7474
bool hasMatchingETag = SetETagResponseHeader(request, response, responseContent);
@@ -132,15 +132,15 @@ private static object WrapErrors(object contextObject)
132132
{
133133
if (contextObject is IEnumerable<ErrorObject> errors)
134134
{
135-
return new ErrorDocument
135+
return new Document
136136
{
137137
Errors = errors.ToList()
138138
};
139139
}
140140

141141
if (contextObject is ErrorObject error)
142142
{
143-
return new ErrorDocument
143+
return new Document
144144
{
145145
Errors = error.AsList()
146146
};

src/JsonApiDotNetCore/Serialization/Objects/AtomicOperationsDocument.cs

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/JsonApiDotNetCore/Serialization/Objects/Document.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1+
using System;
12
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Net;
25
using Newtonsoft.Json;
36

47
namespace JsonApiDotNetCore.Serialization.Objects
58
{
69
/// <summary>
7-
/// See https://jsonapi.org/format/1.1/#document-top-level.
10+
/// See https://jsonapi.org/format/1.1/#document-top-level and https://jsonapi.org/ext/atomic/#document-structure.
811
/// </summary>
912
public sealed class Document : ExposableData<ResourceObject>
1013
{
14+
[JsonProperty("atomic:operations", NullValueHandling = NullValueHandling.Ignore)]
15+
public IList<AtomicOperationObject> Operations { get; set; }
16+
17+
[JsonProperty("atomic:results", NullValueHandling = NullValueHandling.Ignore)]
18+
public IList<AtomicResultObject> Results { get; set; }
19+
20+
[JsonProperty("errors", NullValueHandling = NullValueHandling.Ignore)]
21+
public IList<ErrorObject> Errors { get; set; }
22+
1123
[JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)]
1224
public IDictionary<string, object> Meta { get; set; }
1325

@@ -19,5 +31,23 @@ public sealed class Document : ExposableData<ResourceObject>
1931

2032
[JsonProperty("included", NullValueHandling = NullValueHandling.Ignore, Order = 1)]
2133
public IList<ResourceObject> Included { get; set; }
34+
35+
internal HttpStatusCode GetErrorStatusCode()
36+
{
37+
if (Errors.IsNullOrEmpty())
38+
{
39+
throw new InvalidOperationException("No errors found.");
40+
}
41+
42+
int[] statusCodes = Errors.Select(error => (int)error.StatusCode).Distinct().ToArray();
43+
44+
if (statusCodes.Length == 1)
45+
{
46+
return (HttpStatusCode)statusCodes[0];
47+
}
48+
49+
int statusCode = int.Parse($"{statusCodes.Max().ToString()[0]}00");
50+
return (HttpStatusCode)statusCode;
51+
}
2252
}
2353
}

src/JsonApiDotNetCore/Serialization/Objects/ErrorDocument.cs

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/JsonApiDotNetCore/Serialization/RequestDeserializer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ public object Deserialize(string body)
7575

7676
private object DeserializeOperationsDocument(string body)
7777
{
78-
AtomicOperationsDocument document;
78+
Document document;
7979

8080
using (CodeTimingSessionManager.Current.Measure("Newtonsoft.Deserialize", MeasurementSettings.ExcludeJsonSerializationInPercentages))
8181
{
8282
JToken bodyToken = LoadJToken(body);
83-
document = bodyToken.ToObject<AtomicOperationsDocument>();
83+
document = bodyToken.ToObject<Document>();
8484
}
8585

8686
if ((document?.Operations).IsNullOrEmpty())

src/JsonApiDotNetCore/Serialization/ResponseSerializer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,17 @@ public string Serialize(object content)
7272
return SerializeMany(collectionOfIdentifiable.ToArray());
7373
}
7474

75-
if (content is ErrorDocument errorDocument)
75+
if (content is Document errorDocument)
7676
{
7777
return SerializeErrorDocument(errorDocument);
7878
}
7979

8080
throw new InvalidOperationException("Data being returned must be errors or resources.");
8181
}
8282

83-
private string SerializeErrorDocument(ErrorDocument errorDocument)
83+
private string SerializeErrorDocument(Document document)
8484
{
85-
return SerializeObject(errorDocument, _options.SerializerSettings, serializer =>
85+
return SerializeObject(document, _options.SerializerSettings, serializer =>
8686
{
8787
serializer.ApplyErrorSettings();
8888
});

test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/ArchiveTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ public async Task Cannot_create_archived_resource()
457457
const string route = "/televisionBroadcasts";
458458

459459
// Act
460-
(HttpResponseMessage httpResponse, ErrorDocument responseDocument) = await _testContext.ExecutePostAsync<ErrorDocument>(route, requestBody);
460+
(HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecutePostAsync<Document>(route, requestBody);
461461

462462
// Assert
463463
httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden);
@@ -589,7 +589,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
589589
string route = $"/televisionBroadcasts/{broadcast.StringId}";
590590

591591
// Act
592-
(HttpResponseMessage httpResponse, ErrorDocument responseDocument) = await _testContext.ExecutePatchAsync<ErrorDocument>(route, requestBody);
592+
(HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecutePatchAsync<Document>(route, requestBody);
593593

594594
// Assert
595595
httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden);
@@ -648,7 +648,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
648648
string route = $"/televisionBroadcasts/{broadcast.StringId}";
649649

650650
// Act
651-
(HttpResponseMessage httpResponse, ErrorDocument responseDocument) = await _testContext.ExecuteDeleteAsync<ErrorDocument>(route);
651+
(HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteDeleteAsync<Document>(route);
652652

653653
// Assert
654654
httpResponse.Should().HaveStatusCode(HttpStatusCode.Forbidden);

test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Controllers/AtomicConstrainedOperationsControllerTests.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ public async Task Can_create_resources_for_matching_resource_type()
6262
const string route = "/operations/musicTracks/create";
6363

6464
// Act
65-
(HttpResponseMessage httpResponse, AtomicOperationsDocument responseDocument) =
66-
await _testContext.ExecutePostAtomicAsync<AtomicOperationsDocument>(route, requestBody);
65+
(HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecutePostAtomicAsync<Document>(route, requestBody);
6766

6867
// Assert
6968
httpResponse.Should().HaveStatusCode(HttpStatusCode.OK);
@@ -96,7 +95,7 @@ public async Task Cannot_create_resource_for_mismatching_resource_type()
9695
const string route = "/operations/musicTracks/create";
9796

9897
// Act
99-
(HttpResponseMessage httpResponse, ErrorDocument responseDocument) = await _testContext.ExecutePostAtomicAsync<ErrorDocument>(route, requestBody);
98+
(HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecutePostAtomicAsync<Document>(route, requestBody);
10099

101100
// Assert
102101
httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity);
@@ -144,7 +143,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
144143
const string route = "/operations/musicTracks/create";
145144

146145
// Act
147-
(HttpResponseMessage httpResponse, ErrorDocument responseDocument) = await _testContext.ExecutePostAtomicAsync<ErrorDocument>(route, requestBody);
146+
(HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecutePostAtomicAsync<Document>(route, requestBody);
148147

149148
// Assert
150149
httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity);
@@ -199,7 +198,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
199198
const string route = "/operations/musicTracks/create";
200199

201200
// Act
202-
(HttpResponseMessage httpResponse, ErrorDocument responseDocument) = await _testContext.ExecutePostAtomicAsync<ErrorDocument>(route, requestBody);
201+
(HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecutePostAtomicAsync<Document>(route, requestBody);
203202

204203
// Assert
205204
httpResponse.Should().HaveStatusCode(HttpStatusCode.UnprocessableEntity);

0 commit comments

Comments
 (0)