JsonResult Response from WebAPI for Elasticsearch NEST query



我创建了WEBAPI方法,使用NEST搜索ES。使用 ES 进行搜索按预期工作。我遇到的问题是当我尝试使用 POSTMAN 返回 Json(响应( 时,它会引发以下异常:

{ "消息": "发生错误。 "ExceptionMessage": "如果您使用自定义合约解析器,请确保从 ElasticContractResolver 进行子类化", "异常类型": "系统异常", "StackTrace": " at Nest.JsonExtensions.GetConnectionSettings(JsonSerializer 序列化程序(\r 在 Nest.VerbatimDictionaryKeysJsonConverter2.WriteJson(JsonWriter writer, Object value, JsonSerializer serializer)rn at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeConvertable(JsonWriter writer, JsonConverter converter, Object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)rn at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)rn at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)rn at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)rn at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)rn at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)rn at System.Web.Http.Results.JsonResult1.Serialize((\r at System.Web.Http.Results.JsonResult1.Execute()rn at System.Web.Http.Results.JsonResult1.ExecuteAsync(CancelToken 取消令牌(\r at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext((\r--- 从引发异常的上一个位置的堆栈跟踪结束 ---\r at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task 任务(\r 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task 任务(\r 在 System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext((\r--- 从引发异常的上一个位置的堆栈跟踪结束 ---\r at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task 任务(\r 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task 任务(\r 在 System.Web.Http.Controllers.AuthenticationFilterResult.d__0.MoveNext((\r--- 从引发异常的上一个位置的堆栈跟踪结束 ---\r at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task 任务(\r 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task 任务(\r 在 System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext((" }

这是我的 WEB API 方法

[System.Web.Http.Route("SearchElastic")]
[System.Web.Http.HttpPost]
public JsonResult<ISearchResponse<T>> SearchElastic([FromBody] ElasticSearchRequest esRequest)
{
var searchResponse = EsClient.Search<T>(
"...NEST query..."
));
return Json(searchResponse);
}
//<T> is a custom C# class.

我正在使用Elasticsearch/NEST 5.x。

错误消息提示问题所在

{ "消息": "发生错误。", "异常消息": "如果您使用 自定义协定解析程序确保从 ElasticContractResolver", "ExceptionType": "System.Exception", "堆栈跟踪":"在...

它与线有关

return Json(searchResponse);

Web API 使用的 Json 序列化程序的配置不知道如何处理从 NEST 序列化某些类型,因为其中一些类型需要ElasticContractResolver才能正确序列化。

有几种方法可以解决这个问题,但最直接的两种是:

  1. 将 Web API 使用的 Json 序列化程序配置为JsonSerializerSettings上的IContractResolverElasticContractResolver。这里的缺点是,你序列化为 json 的所有类型都将通过 NEST 的解析器。

  2. 通过使用低级客户端从 Elasticsearch 返回字符串或字节数组,避免来自 Elasticsearch 的反序列化/重新序列化循环 ->由 NEST 反序列化 ->完全由 Web API 重新序列化。如果您不对searchResponse进行任何反省,我会推荐这种方法。如果确实需要检查searchResponse,则始终可以将字符串或字节数组反序列化为SearchResponse<T>作为单独的步骤。

这是在NEST 6.x中删除对 Json.NET 的直接依赖的原因之一

最新更新