Skip to content

Commit 99d3277

Browse files
committed
增加JsonDateTimeConverter和JsonDateTimeAttribute
1 parent 7af0260 commit 99d3277

File tree

6 files changed

+171
-298
lines changed

6 files changed

+171
-298
lines changed

WebApiClientCore.Test/Serialization/JsonConverters/JsonCompatibleConverterTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public void DateTimeReaderTest()
4040
public void DateTimeOffsetReaderTest()
4141
{
4242
var options = new JsonSerializerOptions();
43-
options.Converters.Add(JsonCompatibleConverter.DateTimeOffsetReader);
43+
options.Converters.Add(JsonCompatibleConverter.DateTimeReader);
4444

4545
var json = "\"2010-10-10 10:10\"";
4646
var dateTime = JsonSerializer.Deserialize<DateTimeOffset>(json, options);

WebApiClientCore/HttpApiOptions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ private static JsonSerializerOptions CreateJsonDeserializeOptions()
9797
var options = CreateJsonSerializeOptions();
9898
options.Converters.Add(JsonCompatibleConverter.EnumReader);
9999
options.Converters.Add(JsonCompatibleConverter.DateTimeReader);
100-
options.Converters.Add(JsonCompatibleConverter.DateTimeOffsetReader);
101100
return options;
102101
}
103102
}
Lines changed: 3 additions & 226 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using System;
2-
using System.Runtime.CompilerServices;
3-
using System.Text.Json;
4-
using System.Text.Json.Serialization;
1+
using System.Text.Json.Serialization;
52

63
namespace WebApiClientCore.Serialization.JsonConverters
74
{
@@ -13,231 +10,11 @@ public static class JsonCompatibleConverter
1310
/// <summary>
1411
/// 获取Enum类型反序列化兼容的转换器
1512
/// </summary>
16-
public static JsonConverter EnumReader { get; } = new JsonEnumReader();
13+
public static JsonConverter EnumReader { get; } = new JsonStringEnumConverter();
1714

1815
/// <summary>
1916
/// 获取DateTime类型反序列化兼容的转换器
2017
/// </summary>
21-
public static JsonConverter DateTimeReader { get; } = new JsonDateTimeReader();
22-
23-
/// <summary>
24-
/// 获取 DateTimeOffset类型反序列化兼容的转换器
25-
/// </summary>
26-
public static JsonConverter DateTimeOffsetReader { get; } = new JsonDateTimeOffsetReader();
27-
28-
29-
/// <summary>
30-
/// 表示DateTime的本地格式化Json转换器
31-
/// </summary>
32-
private class JsonDateTimeReader : JsonConverter<DateTime>
33-
{
34-
/// <summary>
35-
/// 读取时间
36-
/// 统一转换为本地时间
37-
/// </summary>
38-
/// <param name="reader"></param>
39-
/// <param name="typeToConvert"></param>
40-
/// <param name="options"></param>
41-
/// <returns></returns>
42-
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
43-
{
44-
if (reader.TokenType == JsonTokenType.String)
45-
{
46-
if (DateTime.TryParse(reader.GetString(), out var dateTime))
47-
{
48-
return dateTime;
49-
}
50-
}
51-
return reader.GetDateTime();
52-
}
53-
54-
/// <summary>
55-
/// 写入时间
56-
/// </summary>
57-
/// <param name="writer"></param>
58-
/// <param name="value"></param>
59-
/// <param name="options"></param>
60-
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
61-
{
62-
throw new NotSupportedException();
63-
}
64-
}
65-
66-
67-
/// <summary>
68-
/// 表示DateTimeOffset的本地格式化Json转换器
69-
/// </summary>
70-
private class JsonDateTimeOffsetReader : JsonConverter<DateTimeOffset>
71-
{
72-
/// <summary>
73-
/// 读取时间
74-
/// 统一转换为本地时间
75-
/// </summary>
76-
/// <param name="reader"></param>
77-
/// <param name="typeToConvert"></param>
78-
/// <param name="options"></param>
79-
/// <returns></returns>
80-
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
81-
{
82-
if (reader.TokenType == JsonTokenType.String)
83-
{
84-
if (DateTimeOffset.TryParse(reader.GetString(), out var dateTime))
85-
{
86-
return dateTime;
87-
}
88-
}
89-
return reader.GetDateTimeOffset();
90-
}
91-
92-
/// <summary>
93-
/// 写入时间
94-
/// </summary>
95-
/// <param name="writer"></param>
96-
/// <param name="value"></param>
97-
/// <param name="options"></param>
98-
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
99-
{
100-
throw new NotSupportedException();
101-
}
102-
}
103-
104-
/// <summary>
105-
/// Enum读取器
106-
/// </summary>
107-
private class JsonEnumReader : JsonConverterFactory
108-
{
109-
/// <summary>
110-
/// 是否支持转换
111-
/// </summary>
112-
/// <param name="typeToConvert"></param>
113-
/// <returns></returns>
114-
public override bool CanConvert(Type typeToConvert)
115-
{
116-
return typeToConvert.IsEnum;
117-
}
118-
119-
/// <summary>
120-
/// 创建转换器
121-
/// </summary>
122-
/// <param name="typeToConvert"></param>
123-
/// <param name="options"></param>
124-
/// <returns></returns>
125-
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
126-
{
127-
var converterType = typeof(JsonEnumConverter<>).MakeGenericType(typeToConvert);
128-
return converterType.CreateInstance<JsonConverter>();
129-
}
130-
131-
/// <summary>
132-
/// 枚举转换器
133-
/// </summary>
134-
/// <typeparam name="T"></typeparam>
135-
private class JsonEnumConverter<T> : JsonConverter<T> where T : struct, Enum
136-
{
137-
/// <summary>
138-
/// 类型码
139-
/// </summary>
140-
private static readonly TypeCode typeCode = Type.GetTypeCode(typeof(T));
141-
142-
/// <summary>
143-
/// 是否支持转换
144-
/// </summary>
145-
/// <param name="type"></param>
146-
/// <returns></returns>
147-
public override bool CanConvert(Type type)
148-
{
149-
return type.IsEnum;
150-
}
151-
152-
/// <summary>
153-
/// 读取枚举
154-
/// </summary>
155-
/// <param name="reader"></param>
156-
/// <param name="typeToConvert"></param>
157-
/// <param name="options"></param>
158-
/// <returns></returns>
159-
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
160-
{
161-
var token = reader.TokenType;
162-
if (token == JsonTokenType.String)
163-
{
164-
var enumString = reader.GetString();
165-
return Enum.Parse<T>(enumString, ignoreCase: true);
166-
}
167-
168-
if (token == JsonTokenType.Number)
169-
{
170-
switch (typeCode)
171-
{
172-
case TypeCode.Int32:
173-
if (reader.TryGetInt32(out int int32))
174-
{
175-
return Unsafe.As<int, T>(ref int32);
176-
}
177-
break;
178-
case TypeCode.UInt32:
179-
if (reader.TryGetUInt32(out uint uint32))
180-
{
181-
return Unsafe.As<uint, T>(ref uint32);
182-
}
183-
break;
184-
185-
case TypeCode.Byte:
186-
if (reader.TryGetByte(out byte byteValue))
187-
{
188-
return Unsafe.As<byte, T>(ref byteValue);
189-
}
190-
break;
191-
case TypeCode.SByte:
192-
if (reader.TryGetSByte(out sbyte sbyteValue))
193-
{
194-
return Unsafe.As<sbyte, T>(ref sbyteValue);
195-
}
196-
break;
197-
198-
case TypeCode.Int64:
199-
if (reader.TryGetInt64(out long int64))
200-
{
201-
return Unsafe.As<long, T>(ref int64);
202-
}
203-
break;
204-
case TypeCode.UInt64:
205-
if (reader.TryGetUInt64(out ulong uint64))
206-
{
207-
return Unsafe.As<ulong, T>(ref uint64);
208-
}
209-
break;
210-
211-
case TypeCode.Int16:
212-
if (reader.TryGetInt16(out short int16))
213-
{
214-
return Unsafe.As<short, T>(ref int16);
215-
}
216-
break;
217-
case TypeCode.UInt16:
218-
if (reader.TryGetUInt16(out ushort uint16))
219-
{
220-
return Unsafe.As<ushort, T>(ref uint16);
221-
}
222-
break;
223-
}
224-
}
225-
226-
var message = Resx.unsupported_ConvertType.Format(reader.TokenType, typeToConvert);
227-
throw new NotSupportedException(message);
228-
}
229-
230-
/// <summary>
231-
/// 写入
232-
/// </summary>
233-
/// <param name="writer"></param>
234-
/// <param name="value"></param>
235-
/// <param name="options"></param>
236-
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
237-
{
238-
throw new NotSupportedException();
239-
}
240-
}
241-
}
18+
public static JsonConverter DateTimeReader { get; } = new JsonDateTimeConverter("O");
24219
}
24320
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Text.Json.Serialization;
3+
4+
namespace WebApiClientCore.Serialization.JsonConverters
5+
{
6+
/// <summary>
7+
/// 表示指定属性的日期时间格式
8+
/// 支持DateTime和DateTimeOffset类型
9+
/// </summary>
10+
[AttributeUsage(AttributeTargets.Property)]
11+
public class JsonDateTimeAttribute : JsonConverterAttribute
12+
{
13+
/// <summary>
14+
/// 日期时间格式
15+
/// </summary>
16+
private readonly string dateTimeFormat;
17+
18+
/// <summary>
19+
/// 指定属性的日期时间格式
20+
/// </summary>
21+
/// <exception cref="ArgumentNullException"></exception>
22+
public JsonDateTimeAttribute(string dateTimeFormat)
23+
{
24+
this.dateTimeFormat = dateTimeFormat ?? throw new ArgumentNullException(nameof(dateTimeFormat));
25+
}
26+
27+
/// <summary>
28+
/// 创建转换器
29+
/// </summary>
30+
/// <param name="typeToConvert"></param>
31+
/// <returns></returns>
32+
public override JsonConverter CreateConverter(Type typeToConvert)
33+
{
34+
return new JsonDateTimeConverter(this.dateTimeFormat);
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)