'"Expected [START_OBJECT] but found [VALUE_STRING]" in Elastic Search API call
I'm doing a elasticsearch post
url: https://...../ap_test_api*/_search/
The query is:
{
"size" : 1,
"query" :
{
"bool" :
{
"must" :
[
{
"match" :
{
"log" : "CtnProvisionOperation"
}
},
{
"range" :
{
"@timestamp" :
{
"gte" : "now-4h"
}
}
}
]
}
},
"_source" :
[
"@timestamp",
"log_processed.event",
"kubernetes.host",
"log"
]
}
It works great in Postman, get the results.
However, when I post the query as a string in c#, it returns this error:
Expected [START_OBJECT] but found [VALUE_STRING]
Here is the code:
public async Task<TResponse> PostAsync<TRequest, TResponse>(string requestUri, TRequest request, KeyValuePair<string, string>[] headerList = null, TimeSpan? timeout = null, bool isXml = false)
{
HttpWebRequest webRequest = null;
HttpWebResponse webResponse = null;
MemoryStream responseStream = null;
try
{
// default is application/json
webRequest = SetupRequest("POST", requestUri);
if (isXml) //For XML Post Support
{
webRequest.ContentType = "application/xml";
webRequest.Accept = "application/xml";
}
if (headerList != null)
{
foreach (var header in headerList)
{
webRequest.Headers.Add(header.Key, header.Value);
}
}
if(timeout.HasValue)
{
webRequest.Timeout = (int)timeout.Value.TotalMilliseconds;
}
// for testing
var json = request.AsJson();
byte[] buffer = await (isXml ? request.AsXml() : request.AsJson()).ReadAsByteArrayAsync().ConfigureAwait(false);
using (var stream = await webRequest.GetRequestStreamAsync().ConfigureAwait(false))
await stream.WriteAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
Array.Clear(buffer, 0, buffer.Length);
using (webResponse = await webRequest.GetResponseAsync().ConfigureAwait(false) as HttpWebResponse)
{
if (webResponse.StatusCode == HttpStatusCode.NotFound)
{
return isXml ? ToXml<TResponse>(null) : ToJSon<TResponse>(null);
}
else
{
responseStream = await GetResponseContentAsync(webResponse).ConfigureAwait(false);
}
}
return isXml ? ToXml<TResponse>(responseStream) : ToJSon<TResponse>(responseStream);
}
catch (TimeoutException)
{
if (webRequest != null) //only bother with aborting if we hit our internal timeout...
{
try
{
webRequest.Abort(); //cant only run sync..if this becomes an issue..may just ignore telling endpoint...
}
catch (Exception)
{
}
}
}
catch(WebException ex)
{
string responseBody = string.Empty;
if (ex.Response.ContentLength > 0)
{
responseBody = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
}
throw new ReadableWebException(responseBody, ex); //Rethrow exception with response content downloaded.
}
catch (Exception ex)
{
throw new EndpointException(requestUri, JsonConvert.SerializeObject(request), ex);
}
return isXml ? ToXml<TResponse>(null) : ToJSon<TResponse>(null);
}
The responseBody is:
{"error":{"root_cause":[{"type":"parsing_exception","reason":"Expected [START_OBJECT] but found [VALUE_STRING]","line":1,"col":1}],"type":"parsing_exception","reason":"Expected [START_OBJECT] but found [VALUE_STRING]","line":1,"col":1},"status":400}
Here is how I call it:
query = @"{""query"":{""bool"":{""must"":[{""match"":{""log"":""CtnProvisionOperation""}},{""range"":{""@timestamp"":{""gte"":""now-4h""}}}]}},""_source"":[""@timestamp"",""log_processed.event"",""kubernetes.host"",""log""]}";
var response = await base.PostAsync<string, string>(url, query);
Anyone knows what is the issue?
Looks like I could use NEST to do the query, however, the issue is: the query string may change often, we want to make the query string as configurable.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
