-
Notifications
You must be signed in to change notification settings - Fork 115
/
Copy pathBsonInputFormatter.cs
88 lines (77 loc) · 2.99 KB
/
BsonInputFormatter.cs
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
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.ObjectPool;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections;
using System.Text;
using System.Threading.Tasks;
namespace WebApiContrib.Core.Formatter.Bson
{
/// <summary>
/// A <see cref="BsonInputFormatter"/> for BSON content
/// </summary>
public class BsonInputFormatter : TextInputFormatter
{
private readonly JsonSerializerSettings _jsonSerializerSettings;
private readonly ObjectPoolProvider _objectPoolProvider;
private ObjectPool<JsonSerializer> _jsonSerializerPool;
public BsonInputFormatter(
JsonSerializerSettings jsonSerializerSettings,
ObjectPoolProvider objectPoolProvider)
{
_jsonSerializerSettings = jsonSerializerSettings;
_objectPoolProvider = objectPoolProvider;
SupportedEncodings.Add(Encoding.Unicode);
SupportedEncodings.Add(Encoding.UTF8);
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/bson"));
}
public override Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
var request = context.HttpContext.Request;
using (var reader = new BsonReader(request.Body))
{
reader.ReadRootValueAsArray = IsEnumerable(context.ModelType);
var successful = true;
EventHandler<ErrorEventArgs> errorHandler = (sender, eventArgs) =>
{
successful = false;
var exception = eventArgs.ErrorContext.Error;
eventArgs.ErrorContext.Handled = true;
};
var jsonSerializer = CreateJsonSerializer();
jsonSerializer.Error += errorHandler;
var type = context.ModelType;
object model;
try
{
model = jsonSerializer.Deserialize(reader, type);
}
finally
{
jsonSerializer.Error -= errorHandler;
_jsonSerializerPool.Return(jsonSerializer);
}
if (successful)
{
return InputFormatterResult.SuccessAsync(model);
}
return InputFormatterResult.FailureAsync();
}
}
private JsonSerializer CreateJsonSerializer()
{
if (_jsonSerializerPool == null)
{
_jsonSerializerPool = _objectPoolProvider.Create(new BsonSerializerObjectPolicy(_jsonSerializerSettings));
}
return _jsonSerializerPool.Get();
}
private bool IsEnumerable(Type type)
{
return type.GetInterface(nameof(IEnumerable)) != null;
}
}
}