-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathJsonApiFormatter.cs
More file actions
127 lines (113 loc) · 5.35 KB
/
JsonApiFormatter.cs
File metadata and controls
127 lines (113 loc) · 5.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web.Http;
using JSONAPI.Documents;
using JSONAPI.Documents.Builders;
using Newtonsoft.Json;
namespace JSONAPI.Json
{
/// <summary>
/// MediaTypeFormatter for JSON API
/// </summary>
public class JsonApiFormatter : JsonMediaTypeFormatter
{
private readonly ISingleResourceDocumentFormatter _singleResourceDocumentFormatter;
private readonly IResourceCollectionDocumentFormatter _resourceCollectionDocumentFormatter;
private readonly IErrorDocumentFormatter _errorDocumentFormatter;
private readonly IErrorDocumentBuilder _errorDocumentBuilder;
/// <summary>
/// Creates a new JsonApiFormatter
/// </summary>
public JsonApiFormatter(ISingleResourceDocumentFormatter singleResourceDocumentFormatter,
IResourceCollectionDocumentFormatter resourceCollectionDocumentFormatter,
IErrorDocumentFormatter errorDocumentFormatter,
IErrorDocumentBuilder errorDocumentBuilder)
{
_singleResourceDocumentFormatter = singleResourceDocumentFormatter;
_resourceCollectionDocumentFormatter = resourceCollectionDocumentFormatter;
_errorDocumentFormatter = errorDocumentFormatter;
_errorDocumentBuilder = errorDocumentBuilder;
SupportedMediaTypes.Clear();
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/vnd.api+json"));
}
public override bool CanReadType(Type t)
{
return true;
}
public override bool CanWriteType(Type t)
{
return true;
}
public override async Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
if (type == typeof(IJsonApiDocument) && value == null)
return;
var contentHeaders = content == null ? null : content.Headers;
var effectiveEncoding = SelectCharacterEncoding(contentHeaders);
var writer = CreateJsonWriter(typeof(object), writeStream, effectiveEncoding);
var singleResourceDocument = value as ISingleResourceDocument;
var resourceCollectionDocument = value as IResourceCollectionDocument;
var errorDocument = value as IErrorDocument;
if (singleResourceDocument != null)
{
await _singleResourceDocumentFormatter.Serialize(singleResourceDocument, writer);
}
else if (resourceCollectionDocument != null)
{
await _resourceCollectionDocumentFormatter.Serialize(resourceCollectionDocument, writer);
}
else if (errorDocument != null)
{
await _errorDocumentFormatter.Serialize(errorDocument, writer);
}
else
{
var error = value as HttpError;
if (error != null)
{
var httpErrorDocument = _errorDocumentBuilder.BuildFromHttpError(error, HttpStatusCode.InternalServerError);
await _errorDocumentFormatter.Serialize(httpErrorDocument, writer);
}
else
{
WriteErrorForUnsupportedType(value, writer);
}
}
writer.Flush();
}
public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
var contentHeaders = content == null ? null : content.Headers;
var effectiveEncoding = SelectCharacterEncoding(contentHeaders);
var reader = CreateJsonReader(typeof(IDictionary<string, object>), readStream,
effectiveEncoding);
reader.DateParseHandling = DateParseHandling.None; // We will decide whether to parse as a DateTime or DateTimeOffset according to the attribute type
reader.Read();
if (typeof(ISingleResourceDocument).IsAssignableFrom(type))
return await _singleResourceDocumentFormatter.Deserialize(reader, "");
if (typeof(IResourceCollectionDocument).IsAssignableFrom(type))
return await _resourceCollectionDocumentFormatter.Deserialize(reader, "");
throw new Exception(string.Format("The type {0} is not supported for deserialization.", type.Name));
}
private void WriteErrorForUnsupportedType(object obj, JsonWriter writer)
{
writer.WriteStartObject();
writer.WritePropertyName("title");
writer.WriteValue("Unexpected Content");
writer.WritePropertyName("detail");
writer.WriteValue("The JsonApiFormatter was asked to serialize an unsupported object.");
writer.WritePropertyName("meta");
writer.WriteStartObject();
writer.WritePropertyName("objectTypeName");
writer.WriteValue(obj.GetType().Name);
writer.WriteEndObject();
writer.WriteEndObject();
}
}
}