ASP.NET Core 3.1对接Elasticsearch时NewtonSoft JsonConverter不触发问题
问题核心原因
你在ConfigureServices中配置的AddNewtonsoftJson仅作用于ASP.NET Core MVC的请求/响应序列化流程,Elasticsearch .NET客户端(NEST)的反序列化逻辑完全独立,不会复用MVC的序列化配置。升级后新版本的NEST默认使用内置序列化逻辑/System.Text.Json进行反序列化,自然无法识别你加的Newtonsoft.Json专属的[JsonConverter]特性,也不会触发自定义转换器逻辑。
解决方案1:配置NEST使用Newtonsoft.Json序列化器(适配现有代码)
改造成本最低,可直接复用已完成的MetadataDescriptionConverter逻辑:
- 安装对应版本的NEST Newtonsoft.Json扩展包(7.x版本NEST对应包为
Nest.JsonSerializer.Newtonsoft,版本号需和你引用的NEST主包保持一致):
<PackageReference Include="Nest.JsonSerializer.Newtonsoft" Version="你的NEST版本号" />
- 初始化
ElasticClient时,指定使用Newtonsoft序列化器并注册自定义转换器:
var esSettings = new ConnectionSettings(new Uri("你的Elasticsearch服务地址")) // 启用Newtonsoft.Json序列化器 .UseNewtonsoftJsonSerializer((jsonSettings) => { // 注册自定义转换器 jsonSettings.Converters.Add(new MetadataDescriptionConverter()); }) // 保留其他原有配置,比如默认索引、认证信息等 .DefaultIndex("myindex"); var client = new ElasticClient(esSettings);
如果通过DI注入ElasticClient,将上述配置逻辑放到ConfigureServices的服务注册代码中即可。
解决方案2:改用System.Text.Json自定义转换器
如果不想引入额外的NEST扩展包,可把现有转换器改造成System.Text.Json版本:
- 实现兼容单值/数组的STJ转换器:
using System.Text.Json; using System.Text.Json.Serialization; public class MetadataDescriptionConverter : JsonConverter<string> { public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 处理数组格式的返回值 if (reader.TokenType == JsonTokenType.StartArray) { var descList = new List<string>(); while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) { descList.Add(reader.GetString()); } // 可按需调整数组项的拼接分隔符 return string.Join(Environment.NewLine, descList); } // 处理常规字符串格式 if (reader.TokenType == JsonTokenType.String) { return reader.GetString(); } return null; } public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { writer.WriteStringValue(value); } }
- 替换模型属性的特性为System.Text.Json专属版本:
// 注意此处特性所属命名空间为System.Text.Json.Serialization [JsonPropertyName("metatag.description")] [JsonConverter(typeof(MetadataDescriptionConverter))] public string Description { get; set; }
补充:Newtonsoft版本转换器逻辑完善
你当前的转换器仅保留了空实现,可参考以下代码补充兼容逻辑:
public override bool CanConvert(Type objectType) { return objectType == typeof(string); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.StartArray) { var array = JArray.Load(reader); return string.Join(Environment.NewLine, array.Select(x => x.Value<string>())); } if (reader.TokenType == JsonToken.String) { return reader.Value?.ToString(); } return null; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue(value?.ToString()); }
内容的提问来源于stack exchange,提问作者ThatBlairGuy
相关产品推荐
相关产品推荐

