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
|
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tango.Core.Bson
{
public static class BsonConvert
{
private static BsonUtcSerializer _serializer;
static BsonConvert()
{
_serializer = new BsonUtcSerializer();
}
public static byte[] Serialize(Object obj)
{
MemoryStream ms = new MemoryStream();
using (BsonWriter writer = new BsonWriter(ms))
{
_serializer.Serialize(writer, obj);
return ms.ToArray();
}
}
public static byte[] Serialize<T>(T obj)
{
return Serialize((Object)obj);
}
public static Object Deserialize(byte[] data, Type type)
{
MemoryStream ms = new MemoryStream(data);
using (BsonReader reader = new BsonReader(ms))
{
Object obj = _serializer.Deserialize(reader, type);
return obj;
}
}
public static T Deserialize<T>(byte[] data)
{
return (T)Deserialize(data, typeof(T));
}
}
public class BsonUtcSerializer : JsonSerializer
{
private class DateTimeConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(DateTime) == objectType
|| typeof(DateTime?) == objectType;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var dateTimeOffset = (DateTime)value;
// Serialize DateTimeOffset as round-trip formatted string
serializer.Serialize(writer, dateTimeOffset.ToString("O"));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Date)
return null;
DateTime dt;
var dateWithOffset = (String)reader.Value;
if (String.IsNullOrEmpty(dateWithOffset))
return null;
if (DateTime.TryParseExact(dateWithOffset, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dt))
return dt;
return null;
}
}
private class DateTimeContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
var contract = base.CreateContract(objectType);
if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
contract.Converter = new DateTimeConverter();
return contract;
}
}
public BsonUtcSerializer()
{
ContractResolver = new DateTimeContractResolver();
DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
}
}
}
|