-
Notifications
You must be signed in to change notification settings - Fork 331
/
Copy pathDefaultJsonSerializer.cs
128 lines (117 loc) · 4.55 KB
/
DefaultJsonSerializer.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
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
128
using EasyCaching.Core.Internal;
using EasyCaching.Core.Serialization;
using System;
using System.IO;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
namespace EasyCaching.Serialization.SystemTextJson
{
/// <summary>
/// Default json serializer.
/// </summary>
public class DefaultJsonSerializer : IEasyCachingSerializer
{
/// <summary>
/// The json serializer.
/// </summary>
private readonly JsonSerializerOptions jsonSerializerOption;
/// <summary>
/// The option for Utf8JsonWriter.
/// </summary>
private readonly JsonWriterOptions _jsonWriterOption;
/// <summary>
/// The name.
/// </summary>
private readonly string _name;
/// <summary>
/// Gets the name.
/// </summary>
/// <value>The name.</value>
public string Name => _name;
/// <summary>
/// Initializes a new instance of the <see cref="T:EasyCaching.Serialization.SystemTextJson.DefaultJsonSerializer"/> class.
/// </summary>
/// <param name="name">Name.</param>
/// <param name="serializerSettings">serializerSettings.</param>
public DefaultJsonSerializer(string name, JsonSerializerOptions serializerSettings)
{
_name = name;
jsonSerializerOption = serializerSettings;
// NOTE: We must use UnsafeRelaxedJsonEscaping instead of the encoder from JsonSerializerOptions,
// because we must ensure that the plus sign '+', which is the part of a nested class, is not escaped when writing type name.
_jsonWriterOption = new JsonWriterOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
}
/// <summary>
/// Deserialize the specified bytes.
/// </summary>
/// <returns>The deserialize.</returns>
/// <param name="bytes">Bytes.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public T Deserialize<T>(byte[] bytes)
{
return JsonSerializer.Deserialize<T>(bytes, jsonSerializerOption);
}
/// <summary>
/// Deserialize the specified bytes.
/// </summary>
/// <returns>The deserialize.</returns>
/// <param name="bytes">Bytes.</param>
/// <param name="type">Type.</param>
public object Deserialize(byte[] bytes, Type type)
{
return JsonSerializer.Deserialize(bytes, type, jsonSerializerOption);
}
/// <summary>
/// Deserializes the object.
/// </summary>
/// <returns>The object.</returns>
/// <param name="value">Value.</param>
public object DeserializeObject(ArraySegment<byte> value)
{
var jr = new Utf8JsonReader(value); // the JsonReaderOptions will be used here, which works well.
jr.Read();
if (jr.TokenType == JsonTokenType.StartArray)
{
jr.Read();
var typeName = Encoding.UTF8.GetString(jr.ValueSpan.ToArray());
var type = Type.GetType(typeName, throwOnError: true);
jr.Read();
return JsonSerializer.Deserialize(ref jr, type, jsonSerializerOption);
}
else
{
throw new InvalidDataException("JsonTranscoder only supports [\"TypeName\", object]");
}
}
/// <summary>
/// Serialize the specified value.
/// </summary>
/// <returns>The serialize.</returns>
/// <param name="value">Value.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public byte[] Serialize<T>(T value)
{
return JsonSerializer.SerializeToUtf8Bytes(value, jsonSerializerOption);
}
/// <summary>
/// Serializes the object.
/// </summary>
/// <returns>The object.</returns>
/// <param name="obj">Object.</param>
public ArraySegment<byte> SerializeObject(object obj)
{
var typeName = TypeHelper.BuildTypeName(obj.GetType());
using (var ms = new MemoryStream())
using (var jw = new Utf8JsonWriter(ms, _jsonWriterOption))
{
jw.WriteStartArray();
jw.WriteStringValue(typeName);
JsonSerializer.Serialize(jw, obj, jsonSerializerOption);
jw.WriteEndArray();
jw.Flush();
return new ArraySegment<byte>(ms.ToArray(), 0, (int)ms.Length);
}
}
}
}