Skip to content

Commit 2896850

Browse files
committed
fix(errors): error objects should be a collection
1 parent f285ee9 commit 2896850

File tree

4 files changed

+61
-24
lines changed

4 files changed

+61
-24
lines changed

src/JsonApiDotNetCore/Formatters/JsonApiOutputFormatter.cs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,36 +37,52 @@ public async Task WriteAsync(OutputFormatterWriteContext context)
3737
using (var writer = context.WriterFactory(response.Body, Encoding.UTF8))
3838
{
3939
var jsonApiContext = GetService<IJsonApiContext>(context);
40-
40+
41+
response.ContentType = "application/vnd.api+json";
4142
string responseContent;
4243
try
4344
{
44-
if(context.Object.GetType() == typeof(Error) || jsonApiContext.RequestEntity == null)
45-
{
46-
logger?.LogInformation("Response was not a JSONAPI entity. Serializing as plain JSON.");
47-
responseContent = JsonConvert.SerializeObject(context.Object);
48-
}
49-
else
50-
{
51-
response.ContentType = "application/vnd.api+json";
52-
responseContent = JsonApiSerializer.Serialize(context.Object, jsonApiContext);
53-
}
45+
responseContent = GetResponseBody(context.Object, jsonApiContext, logger);
5446
}
55-
catch(Exception e)
47+
catch (Exception e)
5648
{
5749
logger?.LogError(new EventId(), e, "An error ocurred while formatting the response");
58-
responseContent = new Error("400", e.Message).GetJson();
50+
var errors = new ErrorCollection();
51+
errors.Add(new Error("400", e.Message));
52+
responseContent = errors.GetJson();
5953
response.StatusCode = 400;
6054
}
61-
55+
6256
await writer.WriteAsync(responseContent);
63-
await writer.FlushAsync();
57+
await writer.FlushAsync();
6458
}
6559
}
6660

6761
private T GetService<T>(OutputFormatterWriteContext context)
6862
{
6963
return context.HttpContext.RequestServices.GetService<T>();
7064
}
65+
66+
private string GetResponseBody(object responseObject, IJsonApiContext jsonApiContext, ILogger logger)
67+
{
68+
if (responseObject.GetType() == typeof(Error) || jsonApiContext.RequestEntity == null)
69+
{
70+
if (responseObject.GetType() == typeof(Error))
71+
{
72+
var errors = new ErrorCollection();
73+
errors.Add((Error)responseObject);
74+
return errors.GetJson();
75+
}
76+
else
77+
{
78+
logger?.LogInformation("Response was not a JSONAPI entity. Serializing as plain JSON.");
79+
return JsonConvert.SerializeObject(responseObject);
80+
}
81+
}
82+
else
83+
{
84+
return JsonApiSerializer.Serialize(responseObject, jsonApiContext);
85+
}
86+
}
7187
}
7288
}

src/JsonApiDotNetCore/Internal/Error.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,5 @@ public Error(string status, string title, string detail)
2828

2929
[JsonProperty("status")]
3030
public string Status { get; set; }
31-
32-
public string GetJson()
33-
{
34-
return JsonConvert.SerializeObject(this, new JsonSerializerSettings {
35-
NullValueHandling = NullValueHandling.Ignore
36-
});
37-
}
3831
}
3932
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace JsonApiDotNetCore.Internal
5+
{
6+
public class ErrorCollection
7+
{
8+
public ErrorCollection()
9+
{
10+
Errors = new List<Error>();
11+
}
12+
13+
public List<Error> Errors { get; set; }
14+
15+
public void Add(Error error)
16+
{
17+
Errors.Add(error);
18+
}
19+
20+
public string GetJson()
21+
{
22+
return JsonConvert.SerializeObject(this, new JsonSerializerSettings {
23+
NullValueHandling = NullValueHandling.Ignore
24+
});
25+
}
26+
}
27+
}

test/JsonApiDotNetCoreExampleTests/Acceptance/Spec/QueryParameters.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ public async Task Server_Returns_400_ForUnknownQueryParam()
3939

4040
// act
4141
var response = await client.SendAsync(request);
42-
var body = JsonConvert.DeserializeObject<Error>(await response.Content.ReadAsStringAsync());
42+
var body = JsonConvert.DeserializeObject<ErrorCollection>(await response.Content.ReadAsStringAsync());
4343

4444
// assert
4545
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
46-
Assert.Equal($"[{queryKey}, {queryValue}] is not a valid query.", body.Title);
46+
Assert.Equal(1, body.Errors.Count);
47+
Assert.Equal($"[{queryKey}, {queryValue}] is not a valid query.", body.Errors[0].Title);
4748
}
4849
}
4950
}

0 commit comments

Comments
 (0)