fix(openai): 修复 dynamic 属性序列化错误

This commit is contained in:
Fu Diwei 2022-01-21 11:00:28 +08:00
parent 9f0a5d8600
commit be90a93012
3 changed files with 6 additions and 118 deletions

View File

@ -10,6 +10,7 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("bindlist")]
[System.Text.Json.Serialization.JsonPropertyName("bindlist")]
public object[] BindList { get; set; } = default!;
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.DynamicObjectReadOnlyConverter))]
public dynamic[] BindList { get; set; } = default!;
}
}

View File

@ -1,12 +1,4 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models.Platform
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models.Platform
{
/// <summary>
/// <para>表示 [POST] /nlp/ner/{TOKEN} 接口的响应。</para>
@ -43,7 +35,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models.Platform
/// </summary>
[Newtonsoft.Json.JsonProperty("norm")]
[System.Text.Json.Serialization.JsonPropertyName("norm")]
[System.Text.Json.Serialization.JsonConverter(typeof(DynamicObjectConverter))]
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.DynamicObjectReadOnlyConverter))]
public dynamic Norm { get; set; } = default!;
}
}
@ -55,110 +47,4 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models.Platform
[System.Text.Json.Serialization.JsonPropertyName("result")]
public Types.Result[] ResultList { get; set; } = default!;
}
public class DynamicObjectConverter : JsonConverter<dynamic?>
{
public override bool CanConvert(Type typeToConvert)
{
return base.CanConvert(typeToConvert) || typeof(IDynamicMetaObjectProvider).IsAssignableFrom(typeToConvert);
}
public override dynamic? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return ReadValue(ref reader, options);
}
public override void Write(Utf8JsonWriter writer, dynamic? value, JsonSerializerOptions options)
{
}
private object? ReadValue(ref Utf8JsonReader reader, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.None:
case JsonTokenType.Null:
return null;
case JsonTokenType.True:
return true;
case JsonTokenType.False:
return false;
case JsonTokenType.Number:
return reader.TryGetInt64(out long longValue) ? longValue : reader.GetDouble();
case JsonTokenType.String:
return reader.GetString();
case JsonTokenType.StartObject:
return ReadObject(ref reader, options);
case JsonTokenType.StartArray:
return ReadArray(ref reader, options);
default:
return JsonNode.Parse(ref reader, new JsonNodeOptions() { PropertyNameCaseInsensitive = options.PropertyNameCaseInsensitive });
}
}
private object? ReadObject(ref Utf8JsonReader reader, JsonSerializerOptions options)
{
IDictionary<string, object?> expandoObject = new ExpandoObject();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonTokenType.PropertyName:
{
string key = reader.GetString()!;
if (!reader.Read())
{
throw new JsonException("Unexpected end when reading ExpandoObject.");
}
object? value = ReadValue(ref reader, options);
expandoObject[key] = value;
}
break;
case JsonTokenType.Comment:
break;
case JsonTokenType.EndObject:
return expandoObject;
}
}
throw new JsonException("Unexpected end when reading ExpandoObject.");
}
private object? ReadArray(ref Utf8JsonReader reader, JsonSerializerOptions options)
{
IList<object?> list = new List<object?>();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonTokenType.Comment:
break;
case JsonTokenType.EndArray:
return list.ToArray();
default:
{
object? element = ReadValue(ref reader, options);
list.Add(element);
}
break;
}
}
throw new JsonException("Unexpected end when reading ExpandoObject.");
}
}
}

View File

@ -81,7 +81,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("content")]
[System.Text.Json.Serialization.JsonPropertyName("content")]
public object Content { get; set; } = default!;
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.DynamicObjectReadOnlyConverter))]
public dynamic Content { get; set; } = default!;
}
}