feat(core): 抽离公共组件,引入 SKIT.FlurlHttpClient.Common 依赖

This commit is contained in:
Fu Diwei 2021-08-20 22:07:57 +08:00
parent 0ac6c0ea3c
commit 2fd391957a
41 changed files with 8 additions and 1718 deletions

View File

@ -1,32 +0,0 @@
using System;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class CommonDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
private readonly JsonConverter<DateTimeOffset?> _converter = new CommonNullableDateTimeOffsetConverter();
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override DateTimeOffset ReadJson(JsonReader reader, Type objectType, DateTimeOffset existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return _converter.ReadJson(reader, objectType, existingValue, hasExistingValue, serializer) ?? default;
}
public override void WriteJson(JsonWriter writer, DateTimeOffset value, JsonSerializer serializer)
{
_converter.WriteJson(writer, value, serializer);
}
}
}

View File

@ -1,57 +0,0 @@
using System;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class CommonNullableDateTimeOffsetConverter : JsonConverter<DateTimeOffset?>
{
internal const string DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override DateTimeOffset? ReadJson(JsonReader reader, Type objectType, DateTimeOffset? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return existingValue;
}
else if (reader.TokenType == JsonToken.String)
{
string? value = serializer.Deserialize<string>(reader);
if (value == null)
return existingValue;
if (DateTimeOffset.TryParseExact(value, DATETIME_FORMAT, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out DateTimeOffset result))
return result;
if (DateTimeOffset.TryParse(value, out result))
return result;
}
else if (reader.TokenType == JsonToken.Date)
{
reader.DateFormatString = DATETIME_FORMAT;
return serializer.Deserialize<DateTimeOffset>(reader);
}
throw new JsonReaderException();
}
public override void WriteJson(JsonWriter writer, DateTimeOffset? value, JsonSerializer serializer)
{
if (value.HasValue)
writer.WriteValue(value.Value.ToString(DATETIME_FORMAT, DateTimeFormatInfo.InvariantInfo));
else
writer.WriteNull();
}
}
}

View File

@ -1,52 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class JsonTypedStringArrayConverter : JsonConverter<string[]?>
{
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override string[]? ReadJson(JsonReader reader, Type objectType, string[]? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
else if (reader.TokenType == JsonToken.String)
{
string? value = serializer.Deserialize<string>(reader);
if (value == null)
return existingValue;
if (value.StartsWith("[") && value.EndsWith("["))
return JsonConvert.DeserializeObject<string[]>(value);
if (string.IsNullOrEmpty(value))
return new string[0];
else
return new string[1] { value };
}
throw new JsonReaderException();
}
public override void WriteJson(JsonWriter writer, string[]? value, JsonSerializer serializer)
{
if (value != null)
writer.WriteValue(JsonConvert.SerializeObject(value, Formatting.None));
else
writer.WriteNull();
}
}
}

View File

@ -1,44 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class JsonTypedStringIListConverter : JsonConverter<IList<string>?>
{
private readonly JsonConverter<List<string>?> _converter = new JsonTypedStringListConverter();
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override IList<string>? ReadJson(JsonReader reader, Type objectType, IList<string>? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return _converter.ReadJson(reader, objectType, ConvertIListToList(existingValue), hasExistingValue, serializer);
}
public override void WriteJson(JsonWriter writer, IList<string>? value, JsonSerializer serializer)
{
_converter.WriteJson(writer, ConvertIListToList(value), serializer);
}
private List<string>? ConvertIListToList(IList<string>? src)
{
if (src == null)
return null;
List<string>? dest = src as List<string>;
if (dest != null)
return dest;
return new List<string>(src);
}
}
}

View File

@ -1,46 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class JsonTypedStringListConverter : JsonConverter<List<string>?>
{
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override List<string>? ReadJson(JsonReader reader, Type objectType, List<string>? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
else if (reader.TokenType == JsonToken.String)
{
string? value = serializer.Deserialize<string>(reader);
if (value == null)
return existingValue;
return JsonConvert.DeserializeObject<List<string>>(value);
}
throw new JsonReaderException();
}
public override void WriteJson(JsonWriter writer, List<string>? value, JsonSerializer serializer)
{
if (value != null)
writer.WriteValue(JsonConvert.SerializeObject(value, Formatting.None));
else
writer.WriteNull();
}
}
}

View File

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class NumberTypedBooleanConverter : JsonConverter<bool>
{
private readonly JsonConverter<bool?> _converter = new NumberTypedNullableBooleanConverter();
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override bool ReadJson(JsonReader reader, Type objectType, bool existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return _converter.ReadJson(reader, objectType, existingValue, hasExistingValue, serializer) ?? default;
}
public override void WriteJson(JsonWriter writer, bool value, JsonSerializer serializer)
{
_converter.WriteJson(writer, value, serializer);
}
}
}

View File

@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class NumberTypedNullableBooleanConverter : JsonConverter<bool?>
{
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override bool? ReadJson(JsonReader reader, Type objectType, bool? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return existingValue;
}
else if (reader.TokenType == JsonToken.Boolean)
{
return serializer.Deserialize<bool>(reader);
}
else if (reader.TokenType == JsonToken.Integer)
{
int value = serializer.Deserialize<int>(reader);
return Convert.ToBoolean(value);
}
else if (reader.TokenType == JsonToken.String)
{
string? str = serializer.Deserialize<string>(reader);
if (str == null)
return existingValue;
if (int.TryParse(str, out int value))
return Convert.ToBoolean(value);
}
throw new JsonReaderException();
}
public override void WriteJson(JsonWriter writer, bool? value, JsonSerializer serializer)
{
if (value.HasValue)
writer.WriteValue(value.Value ? 1 : 0);
else
writer.WriteNull();
}
}
}

View File

@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class RFC3339DateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
private readonly JsonConverter<DateTimeOffset?> _converter = new RFC3339NullableDateTimeOffsetConverter();
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override DateTimeOffset ReadJson(JsonReader reader, Type objectType, DateTimeOffset existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return _converter.ReadJson(reader, objectType, existingValue, hasExistingValue, serializer) ?? default;
}
public override void WriteJson(JsonWriter writer, DateTimeOffset value, JsonSerializer serializer)
{
_converter.WriteJson(writer, value, serializer);
}
}
}

View File

@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class RFC3339NullableDateTimeOffsetConverter : JsonConverter<DateTimeOffset?>
{
internal const string DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:sszzz";
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override DateTimeOffset? ReadJson(JsonReader reader, Type objectType, DateTimeOffset? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return existingValue;
}
else if (reader.TokenType == JsonToken.String)
{
string? value = serializer.Deserialize<string>(reader);
if (value == null)
return existingValue;
if (DateTimeOffset.TryParseExact(value, DATETIME_FORMAT, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out DateTimeOffset result))
return result;
if (DateTimeOffset.TryParse(value, out result))
return result;
}
else if (reader.TokenType == JsonToken.Date)
{
reader.DateFormatString = DATETIME_FORMAT;
return serializer.Deserialize<DateTimeOffset>(reader);
}
throw new JsonReaderException();
}
public override void WriteJson(JsonWriter writer, DateTimeOffset? value, JsonSerializer serializer)
{
if (value.HasValue)
writer.WriteValue(value.Value.ToString(DATETIME_FORMAT, DateTimeFormatInfo.InvariantInfo));
else
writer.WriteNull();
}
}
}

View File

@ -1,44 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class StringTypedInt32IListConverter : JsonConverter<IList<int>?>
{
private readonly JsonConverter<List<int>?> _converter = new StringTypedInt32ListConverter();
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override IList<int>? ReadJson(JsonReader reader, Type objectType, IList<int>? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return _converter.ReadJson(reader, objectType, ConvertIListToList(existingValue), hasExistingValue, serializer);
}
public override void WriteJson(JsonWriter writer, IList<int>? value, JsonSerializer serializer)
{
_converter.WriteJson(writer, ConvertIListToList(value), serializer);
}
private List<int>? ConvertIListToList(IList<int>? src)
{
if (src == null)
return null;
List<int>? dest = src as List<int>;
if (dest != null)
return dest;
return new List<int>(src);
}
}
}

View File

@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class StringTypedInt32ListConverter : JsonConverter<List<int>?>
{
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override List<int>? ReadJson(JsonReader reader, Type objectType, List<int>? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
else if (reader.TokenType == JsonToken.String)
{
string? value = serializer.Deserialize<string>(reader);
if (value == null)
return existingValue;
try
{
return value.Split(',').Select(e => int.Parse(e.Trim())).ToList();
}
catch (Exception ex)
{
throw new JsonReaderException(ex.Message, ex);
}
}
throw new JsonReaderException();
}
public override void WriteJson(JsonWriter writer, List<int>? value, JsonSerializer serializer)
{
if (value != null)
writer.WriteValue(string.Join(",", value));
else
writer.WriteNull();
}
}
}

View File

@ -1,44 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class StringTypedStringIListConverter : JsonConverter<IList<string>?>
{
private readonly JsonConverter<List<string>?> _converter = new StringTypedStringListConverter();
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override IList<string>? ReadJson(JsonReader reader, Type objectType, IList<string>? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return _converter.ReadJson(reader, objectType, ConvertIListToList(existingValue), hasExistingValue, serializer);
}
public override void WriteJson(JsonWriter writer, IList<string>? value, JsonSerializer serializer)
{
_converter.WriteJson(writer, ConvertIListToList(value), serializer);
}
private List<string>? ConvertIListToList(IList<string>? src)
{
if (src == null)
return null;
List<string>? dest = src as List<string>;
if (dest != null)
return dest;
return new List<string>(src);
}
}
}

View File

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Converters
{
public class StringTypedStringListConverter : JsonConverter<List<string>?>
{
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override List<string>? ReadJson(JsonReader reader, Type objectType, List<string>? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
else if (reader.TokenType == JsonToken.String)
{
string? value = serializer.Deserialize<string>(reader);
if (value == null)
return existingValue;
return value.Split(',').ToList();
}
throw new JsonReaderException();
}
public override void WriteJson(JsonWriter writer, List<string>? value, JsonSerializer serializer)
{
if (value != null)
writer.WriteValue(string.Join(",", value));
else
writer.WriteNull();
}
}
}

View File

@ -1,22 +0,0 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class CommonDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
private readonly JsonConverter<DateTimeOffset?> _converter = new CommonNullableDateTimeOffsetConverter();
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return _converter.Read(ref reader, typeToConvert, options) ?? default;
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
{
_converter.Write(writer, value, options);
}
}
}

View File

@ -1,42 +0,0 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class CommonNullableDateTimeOffsetConverter : JsonConverter<DateTimeOffset?>
{
private const string DATETIME_FORMAT = Newtonsoft.Json.Converters.CommonNullableDateTimeOffsetConverter.DATETIME_FORMAT;
public override DateTimeOffset? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
else if (reader.TokenType == JsonTokenType.String)
{
string? value = reader.GetString();
if (value == null)
return null;
if (DateTimeOffset.TryParseExact(value, DATETIME_FORMAT, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out DateTimeOffset result))
return result;
if (DateTimeOffset.TryParse(value, out result))
return result;
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset? value, JsonSerializerOptions options)
{
if (value.HasValue)
writer.WriteStringValue(value.Value.ToString(DATETIME_FORMAT, DateTimeFormatInfo.InvariantInfo));
else
writer.WriteNullValue();
}
}
}

View File

@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class JsonTypedStringArrayConverter : JsonConverter<string[]?>
{
public override string[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
else if (reader.TokenType == JsonTokenType.String)
{
string? value = reader.GetString();
if (value == null)
return null;
if (value.StartsWith("[") && value.EndsWith("["))
return JsonSerializer.Deserialize<string[]>(value, options);
if (string.IsNullOrEmpty(value))
return new string[0];
else
return new string[1] { value };
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, string[]? value, JsonSerializerOptions options)
{
if (value != null)
writer.WriteStringValue(JsonSerializer.Serialize(value, options));
else
writer.WriteNullValue();
}
}
}

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class JsonTypedStringIListConverter : JsonConverter<IList<string>?>
{
private readonly JsonConverter<List<string>?> _converter = new JsonTypedStringListConverter();
public override IList<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return _converter.Read(ref reader, typeToConvert, options);
}
public override void Write(Utf8JsonWriter writer, IList<string>? value, JsonSerializerOptions options)
{
_converter.Write(writer, ConvertIListToList(value), options);
}
private List<string>? ConvertIListToList(IList<string>? src)
{
if (src == null)
return null;
List<string>? dest = src as List<string>;
if (dest != null)
return dest;
return new List<string>(src);
}
}
}

View File

@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class JsonTypedStringListConverter : JsonConverter<List<string>?>
{
public override List<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
else if (reader.TokenType == JsonTokenType.String)
{
string? value = reader.GetString();
if (value == null)
return null;
return JsonSerializer.Deserialize<List<string>>(value, options);
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, List<string>? value, JsonSerializerOptions options)
{
if (value != null)
writer.WriteStringValue(JsonSerializer.Serialize(value, options));
else
writer.WriteNullValue();
}
}
}

View File

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class NumberTypedBooleanConverter : JsonConverter<bool>
{
private readonly JsonConverter<bool?> _converter = new NumberTypedNullableBooleanConverter();
public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return _converter.Read(ref reader, typeToConvert, options) ?? default;
}
public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options)
{
_converter.Write(writer, value, options);
}
}
}

View File

@ -1,50 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class NumberTypedNullableBooleanConverter : JsonConverter<bool?>
{
public override bool? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
else if (reader.TokenType == JsonTokenType.True)
{
return true;
}
else if (reader.TokenType == JsonTokenType.False)
{
return false;
}
else if (reader.TokenType == JsonTokenType.Number)
{
if (reader.TryGetInt32(out int value))
return Convert.ToBoolean(value);
}
else if (reader.TokenType == JsonTokenType.String)
{
string? str = reader.GetString();
if (str == null)
return null;
if (int.TryParse(str, out int value))
return Convert.ToBoolean(value);
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, bool? value, JsonSerializerOptions options)
{
if (value.HasValue)
writer.WriteNumberValue(value.Value ? 1 : 0);
else
writer.WriteNullValue();
}
}
}

View File

@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class NumberTypedStringConverter : JsonConverter<string?>
{
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
else if (reader.TokenType == JsonTokenType.Number)
{
if (reader.TryGetInt64(out long valueAsInt64))
return valueAsInt64.ToString();
else if (reader.TryGetUInt64(out ulong valueAsUInt64))
return valueAsUInt64.ToString();
else if (reader.TryGetDouble(out double valueAsDouble))
return valueAsDouble.ToString();
else
return reader.GetDecimal().ToString();
}
else if (reader.TokenType == JsonTokenType.String)
{
return reader.GetString();
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
{
if (value != null)
{
if (long.TryParse(value, out long valueAsInt64))
writer.WriteNumberValue(valueAsInt64);
else if (ulong.TryParse(value, out ulong valueAsUInt64))
writer.WriteNumberValue(valueAsUInt64);
else if (double.TryParse(value, out double valueAsDouble))
writer.WriteNumberValue(valueAsDouble);
else
writer.WriteStringValue(value);
}
else
{
writer.WriteNullValue();
}
}
}
}

View File

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class RFC3339DateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
private readonly JsonConverter<DateTimeOffset?> _converter = new RFC3339NullableDateTimeOffsetConverter();
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return _converter.Read(ref reader, typeToConvert, options) ?? default;
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
{
_converter.Write(writer, value, options);
}
}
}

View File

@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class RFC3339NullableDateTimeOffsetConverter : JsonConverter<DateTimeOffset?>
{
internal const string DATETIME_FORMAT = Newtonsoft.Json.Converters.RFC3339NullableDateTimeOffsetConverter.DATETIME_FORMAT;
public override DateTimeOffset? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
else if (reader.TokenType == JsonTokenType.String)
{
string? value = reader.GetString();
if (value == null)
return null;
if (DateTimeOffset.TryParseExact(value, DATETIME_FORMAT, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out DateTimeOffset result))
return result;
if (DateTimeOffset.TryParse(value, out result))
return result;
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset? value, JsonSerializerOptions options)
{
if (value.HasValue)
writer.WriteStringValue(value.Value.ToString(DATETIME_FORMAT, DateTimeFormatInfo.InvariantInfo));
else
writer.WriteNullValue();
}
}
}

View File

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class StringTypedBooleanConverter : JsonConverter<bool>
{
private readonly JsonConverter<bool?> _converter = new StringTypedNullableBooleanConverter();
public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return _converter.Read(ref reader, typeToConvert, options) ?? default;
}
public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options)
{
_converter.Write(writer, value, options);
}
}
}

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class StringTypedInt32IListConverter : JsonConverter<IList<int>?>
{
private readonly JsonConverter<List<int>?> _converter = new StringTypedInt32ListConverter();
public override IList<int>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return _converter.Read(ref reader, typeToConvert, options);
}
public override void Write(Utf8JsonWriter writer, IList<int>? value, JsonSerializerOptions options)
{
_converter.Write(writer, ConvertIListToList(value), options);
}
private List<int>? ConvertIListToList(IList<int>? src)
{
if (src == null)
return null;
List<int>? dest = src as List<int>;
if (dest != null)
return dest;
return new List<int>(src);
}
}
}

View File

@ -1,44 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class StringTypedInt32ListConverter : JsonConverter<List<int>?>
{
public override List<int>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
else if (reader.TokenType == JsonTokenType.String)
{
string? value = reader.GetString();
if (value == null)
return null;
try
{
return value.Split(',').Select(e => int.Parse(e.Trim())).ToList();
}
catch (Exception ex)
{
throw new JsonException(ex.Message, ex);
}
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, List<int>? value, JsonSerializerOptions options)
{
if (value != null)
writer.WriteStringValue(string.Join(",", value));
else
writer.WriteNullValue();
}
}
}

View File

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class StringTypedNullableBooleanConverter : JsonConverter<bool?>
{
public override bool? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
else if (reader.TokenType == JsonTokenType.True)
{
return true;
}
else if (reader.TokenType == JsonTokenType.False)
{
return false;
}
else if (reader.TokenType == JsonTokenType.String)
{
string? value = reader.GetString();
if (value == null)
return null;
if ("true".Equals(value, StringComparison.InvariantCultureIgnoreCase))
return true;
else if ("false".Equals(value, StringComparison.InvariantCultureIgnoreCase))
return false;
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, bool? value, JsonSerializerOptions options)
{
if (value.HasValue)
writer.WriteStringValue(value.Value ? "true" : "false");
else
writer.WriteNullValue();
}
}
}

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class StringTypedStringIListConverter : JsonConverter<IList<string>?>
{
private readonly JsonConverter<List<string>?> _converter = new StringTypedStringListConverter();
public override IList<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return _converter.Read(ref reader, typeToConvert, options);
}
public override void Write(Utf8JsonWriter writer, IList<string>? value, JsonSerializerOptions options)
{
_converter.Write(writer, ConvertIListToList(value), options);
}
private List<string>? ConvertIListToList(IList<string>? src)
{
if (src == null)
return null;
List<string>? dest = src as List<string>;
if (dest != null)
return dest;
return new List<string>(src);
}
}
}

View File

@ -1,37 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace System.Text.Json.Converters
{
public class StringTypedStringListConverter : JsonConverter<List<string>?>
{
public override List<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
else if (reader.TokenType == JsonTokenType.String)
{
string? value = reader.GetString();
if (value == null)
return null;
return value.Split(',').ToList();
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, List<string>? value, JsonSerializerOptions options)
{
if (value != null)
writer.WriteStringValue(string.Join(",", value));
else
writer.WriteNullValue();
}
}
}

View File

@ -1,43 +0,0 @@
using System;
using System.Net.Http;
using Flurl;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat
{
public static class FlurlHttpRequestVerbExtensions
{
public static IFlurlRequest WithVerb(this string url, string method)
{
return WithVerb(url, new HttpMethod(method));
}
public static IFlurlRequest WithVerb(this string url, HttpMethod method)
{
return WithVerb(Url.Parse(url), method);
}
public static IFlurlRequest WithVerb(this Url url, string method)
{
return WithVerb(url, new HttpMethod(method));
}
public static IFlurlRequest WithVerb(this Url url, HttpMethod method)
{
return WithVerb(new FlurlRequest(url), method);
}
public static IFlurlRequest WithVerb(this IFlurlRequest request, string method)
{
return WithVerb(request, new HttpMethod(method));
}
public static IFlurlRequest WithVerb(this IFlurlRequest request, HttpMethod method)
{
if (request == null) throw new ArgumentNullException(nameof(request));
request.Verb = method;
return request;
}
}
}

View File

@ -8,22 +8,7 @@ namespace SKIT.FlurlHttpClient.Wechat
/// <summary>
/// SKIT.FlurlHttpClient.Wechat 客户端接口。
/// </summary>
public interface IWechatClient : IDisposable
public interface IWechatClient : ICommonClient
{
/// <summary>
/// 获取当前客户端的拦截器集合。
/// </summary>
public WechatHttpCallInterceptorCollection Interceptors { get; }
/// <summary>
/// 获取当前客户端使用的 JSON 序列化器。
/// </summary>
public ISerializer JsonSerializer { get; }
/// <summary>
/// 配置客户端。
/// </summary>
/// <param name="configure"></param>
public void Configure(Action<WechatClientSettings> configure);
}
}

View File

@ -5,13 +5,7 @@ namespace SKIT.FlurlHttpClient.Wechat
/// <summary>
/// SKIT.FlurlHttpClient.Wechat 请求接口。
/// </summary>
public interface IWechatRequest
public interface IWechatRequest : ICommonRequest
{
/// <summary>
/// 获取或设置请求超时时间(单位:毫秒)。
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public int? Timeout { get; set; }
}
}

View File

@ -6,33 +6,11 @@ namespace SKIT.FlurlHttpClient.Wechat
/// <summary>
/// SKIT.FlurlHttpClient.Wechat 响应接口。
/// </summary>
public interface IWechatResponse
public interface IWechatResponse : ICommonResponse
{
/// <summary>
/// 获取原始的 HTTP 响应状态码
/// 获取微信 API 返回的错误描述
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public int RawStatus { get; }
/// <summary>
/// 获取原始的 HTTP 响应表头集合。
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public IDictionary<string, string> RawHeaders { get; }
/// <summary>
/// 获取原始的 HTTP 响应正文。
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public byte[] RawBytes { get; }
/// <summary>
/// 获取一个值,该值指示调用 API 是否成功。
/// </summary>
/// <returns></returns>
bool IsSuccessful();
string? ErrorMessage { get; set; }
}
}

View File

@ -13,7 +13,7 @@
<PackageProjectUrl>https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat</PackageProjectUrl>
<PackageTags>Flurl.Http Wechat Weixin MicroMessage 微信</PackageTags>
<Version>1.0.3</Version>
<Description>The core of a Flurl.Http client for Wechat. SKIT.FlurlClient.Wechat含 SKIT.FlurlHttpClient.Wechat.Api、SKIT.FlurlHttpClient.Wechat.TenpayV3、SKIT.FlurlHttpClient.Wechat.Work、SKIT.FlurlHttpClient.Wechat.Ads 等模块)的核心库,具体用法请参阅开发文档。</Description>
<Description>SKIT.FlurlClient.Wechat含 SKIT.FlurlHttpClient.Wechat.Api、SKIT.FlurlHttpClient.Wechat.TenpayV3、SKIT.FlurlHttpClient.Wechat.Work、SKIT.FlurlHttpClient.Wechat.Ads 等模块)的核心库,具体用法请参阅开发文档。</Description>
<Authors>Fu Diwei</Authors>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git</RepositoryUrl>
@ -23,11 +23,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Flurl" Version="3.0.2" />
<PackageReference Include="Flurl.Http" Version="3.2.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="System.Text.Encodings.Web" Version="5.0.1" />
<PackageReference Include="System.Text.Json" Version="5.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="1.0.0" />
</ItemGroup>
</Project>

View File

@ -1,75 +0,0 @@
using System;
using System.IO;
using Flurl.Http.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace SKIT.FlurlHttpClient.Wechat
{
public class FlurlNewtonsoftJsonSerializer : ISerializer
{
private readonly JsonSerializerSettings _settings;
public FlurlNewtonsoftJsonSerializer()
: this(GetDefaultSerializerSettings())
{
}
public FlurlNewtonsoftJsonSerializer(JsonSerializerSettings settings)
{
if (settings == null) throw new ArgumentNullException(nameof(settings));
_settings = settings;
}
public static JsonSerializerSettings GetDefaultSerializerSettings()
{
var jsonSettings = new JsonSerializerSettings();
jsonSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
jsonSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
jsonSettings.NullValueHandling = NullValueHandling.Ignore;
jsonSettings.Formatting = Formatting.None;
jsonSettings.ContractResolver = new DefaultContractResolver();
return jsonSettings;
}
public T Deserialize<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json, _settings);
}
T ISerializer.Deserialize<T>(Stream stream)
{
if (stream.CanSeek)
{
stream.Seek(0, SeekOrigin.Begin);
}
using (var reader = new StreamReader(stream))
{
string json = reader.ReadToEnd();
return Deserialize<T>(json);
}
}
public object Deserialize(string json, Type type)
{
return JsonConvert.DeserializeObject(json, type, _settings)!;
}
public string Serialize<T>(T obj)
{
return JsonConvert.SerializeObject(obj, _settings);
}
public string Serialize(object obj)
{
return JsonConvert.SerializeObject(obj, _settings);
}
public string Serialize(object obj, Type type)
{
return JsonConvert.SerializeObject(obj, type, _settings);
}
}
}

View File

@ -1,77 +0,0 @@
using System;
using System.IO;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using Flurl.Http.Configuration;
namespace SKIT.FlurlHttpClient.Wechat
{
public class FlurlSystemTextJsonSerializer : ISerializer
{
private readonly JsonSerializerOptions _options;
public FlurlSystemTextJsonSerializer()
: this(GetDefaultSerializerOptions())
{
}
public FlurlSystemTextJsonSerializer(JsonSerializerOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));
_options = options;
}
public static JsonSerializerOptions GetDefaultSerializerOptions()
{
var jsonOptions = new JsonSerializerOptions();
jsonOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
jsonOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString;
jsonOptions.IgnoreNullValues = true;
jsonOptions.WriteIndented = false;
jsonOptions.PropertyNamingPolicy = null;
jsonOptions.PropertyNameCaseInsensitive = true;
return jsonOptions;
}
public T Deserialize<T>(string json)
{
return JsonSerializer.Deserialize<T>(json, _options)!;
}
T ISerializer.Deserialize<T>(Stream stream)
{
if (stream.CanSeek)
{
stream.Seek(0, SeekOrigin.Begin);
}
using (var reader = new StreamReader(stream))
{
string json = reader.ReadToEnd();
return Deserialize<T>(json);
}
}
public object Deserialize(string json, Type type)
{
return JsonSerializer.Deserialize(json, type, _options)!;
}
public string Serialize<T>(T obj)
{
return JsonSerializer.Serialize(obj, _options);
}
public string Serialize(object obj)
{
return JsonSerializer.Serialize(obj, _options);
}
public string Serialize(object obj, Type type)
{
return JsonSerializer.Serialize(obj, type, _options);
}
}
}

View File

@ -1,142 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http;
using Flurl.Http.Configuration;
namespace SKIT.FlurlHttpClient.Wechat
{
/// <summary>
/// SKIT.FlurlHttpClient.Wechat 客户端基类。
/// </summary>
public abstract class WechatClientBase : IWechatClient
{
/// <summary>
/// <inheritdoc />
/// </summary>
public WechatHttpCallInterceptorCollection Interceptors { get; }
/// <summary>
/// <inheritdoc />
/// </summary>
public ISerializer JsonSerializer
{
get { return FlurlClient.Settings?.JsonSerializer ?? FlurlHttp.GlobalSettings.JsonSerializer; }
}
/// <summary>
/// 获取当前客户端使用的 <see cref="IFlurlClient"/> 对象。
/// </summary>
protected IFlurlClient FlurlClient { get; }
/// <summary>
///
/// </summary>
protected WechatClientBase()
{
Interceptors = new WechatHttpCallInterceptorCollection();
FlurlClient = new FlurlClient();
FlurlClient.Configure(flurlSettings =>
{
flurlSettings.JsonSerializer = new FlurlSystemTextJsonSerializer();
flurlSettings.BeforeCallAsync = async (flurlCall) =>
{
for (int i = 0, len = Interceptors.Count; i < len; i++)
{
await Interceptors[i].BeforeCallAsync(flurlCall);
}
};
flurlSettings.AfterCallAsync = async (flurlCall) =>
{
for (int i = Interceptors.Count - 1; i >= 0; i--)
{
await Interceptors[i].AfterCallAsync(flurlCall);
}
};
});
}
/// <inheritdoc/>
public void Configure(Action<WechatClientSettings> configure)
{
if (configure == null) throw new ArgumentNullException(nameof(configure));
FlurlClient.Configure(flurlSettings =>
{
var settings = new WechatClientSettings();
settings.Timeout = flurlSettings.Timeout;
settings.ConnectionLeaseTimeout = flurlSettings.ConnectionLeaseTimeout;
settings.JsonSerializer = flurlSettings.JsonSerializer;
settings.UrlEncodedSerializer = flurlSettings.UrlEncodedSerializer;
settings.FlurlHttpClientFactory = flurlSettings.HttpClientFactory;
configure.Invoke(settings);
flurlSettings.Timeout = settings.Timeout;
flurlSettings.ConnectionLeaseTimeout = settings.ConnectionLeaseTimeout;
flurlSettings.JsonSerializer = settings.JsonSerializer;
flurlSettings.UrlEncodedSerializer = settings.UrlEncodedSerializer;
flurlSettings.HttpClientFactory = settings.FlurlHttpClientFactory;
});
}
/// <summary>
/// 异步发起请求。
/// </summary>
/// <param name="flurlRequest"></param>
/// <param name="httpContent"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected virtual async Task<IFlurlResponse> SendRequestAsync(IFlurlRequest flurlRequest, HttpContent? httpContent = null, CancellationToken cancellationToken = default)
{
if (flurlRequest == null) throw new ArgumentNullException(nameof(flurlRequest));
var response = await flurlRequest
.WithClient(FlurlClient)
.AllowAnyHttpStatus()
.SendAsync(flurlRequest.Verb, httpContent, cancellationToken)
.ConfigureAwait(false);
return response;
}
/// <summary>
/// 异步发起请求。
/// </summary>
/// <param name="flurlRequest"></param>
/// <param name="data"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected virtual async Task<IFlurlResponse> SendRequestWithJsonAsync(IFlurlRequest flurlRequest, object? data = null, CancellationToken cancellationToken = default)
{
if (flurlRequest == null) throw new ArgumentNullException(nameof(flurlRequest));
if (flurlRequest.Verb == HttpMethod.Get)
{
return await flurlRequest
.WithClient(FlurlClient)
.AllowAnyHttpStatus()
.SendAsync(flurlRequest.Verb, cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
else
{
return await flurlRequest
.WithClient(FlurlClient)
.AllowAnyHttpStatus()
.SendJsonAsync(flurlRequest.Verb, data: data, cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public virtual void Dispose()
{
FlurlClient?.Dispose();
}
}
}

View File

@ -1,43 +0,0 @@
using System;
using Flurl.Http.Configuration;
namespace SKIT.FlurlHttpClient.Wechat
{
/// <summary>
/// SKIT.FlurlHttpClient.Wechat 客户端配置项。
/// </summary>
public sealed class WechatClientSettings
{
/// <summary>
///
/// </summary>
public TimeSpan? Timeout { get; set; }
/// <summary>
///
/// </summary>
public TimeSpan? ConnectionLeaseTimeout { get; set; }
/// <summary>
///
/// </summary>
public ISerializer JsonSerializer { get; set; } = default!;
/// <summary>
///
/// </summary>
public ISerializer UrlEncodedSerializer { get; set; } = default!;
/// <summary>
///
/// </summary>
public IHttpClientFactory FlurlHttpClientFactory { get; set; } = default!;
/// <summary>
///
/// </summary>
internal WechatClientSettings()
{
}
}
}

View File

@ -1,27 +0,0 @@
using System;
namespace SKIT.FlurlHttpClient.Wechat
{
/// <summary>
/// SKIT.FlurlHttpClient.Wechat 引发的异常基类。
/// </summary>
public abstract class WechatExceptionBase : Exception
{
/// <inheritdoc/>
public WechatExceptionBase()
{
}
/// <inheritdoc/>
public WechatExceptionBase(string message)
: base(message)
{
}
/// <inheritdoc/>
public WechatExceptionBase(string message, Exception innerException)
: base(message, innerException)
{
}
}
}

View File

@ -1,24 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat
{
public abstract class WechatHttpCallInterceptor
{
public virtual Task BeforeCallAsync(FlurlCall flurlCall)
{
return Task.CompletedTask;
}
public virtual Task AfterCallAsync(FlurlCall flurlCall)
{
return Task.CompletedTask;
}
}
}

View File

@ -1,49 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SKIT.FlurlHttpClient.Wechat
{
public sealed class WechatHttpCallInterceptorCollection : IEnumerable<WechatHttpCallInterceptor>
{
private readonly IList<WechatHttpCallInterceptor> _list;
public int Count
{
get { return _list.Count; }
}
public WechatHttpCallInterceptor this[int index]
{
get { return _list[index]; }
}
public WechatHttpCallInterceptorCollection()
{
_list = new List<WechatHttpCallInterceptor>();
}
public void Add(WechatHttpCallInterceptor interceptor)
{
_list.Add(interceptor);
}
public void Remove(WechatHttpCallInterceptor interceptor)
{
_list.Remove(interceptor);
}
public IEnumerator<WechatHttpCallInterceptor> GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_list).GetEnumerator();
}
}
}