Elastic.Clients.Elasticsearch .NET client - calling Vector tile search API

I am trying to call the Vector tile search API using the new v8 .NET client but receiving an exception. Specifically 8.9.2 as of writing.

I understand it doesn't have official support in the client, but it appears I should be able to call it via a low level call.

The exception info I am receiving is this:

Unsuccessful (200) low level call on GET: /jarrod-development/_mvt/Geometry/1/1/1
 Exception: Request failed to execute. Call: Status code 200 from: GET /jarrod-development/_mvt/Geometry/1/1/1
# Request:
<Request stream not captured or already read to completion by serializer. Set DisableDirectStreaming() on TransportConfiguration to force it to be set on the response.>

My code looks like this:

var path = $"/jarrod-development/_mvt/Geometry/{dto.Zoom}/{dto.X}/{dto.Y}";
var results = await _elasticClient.Transport.RequestAsync<DynamicResponse>(HttpMethod.GET, path, cancellationToken: ct);

Where "Geometry" is the geo field name on my document.

I have tried the following options:
Changing the HttpMethod to POST
Changing the return type to BytesResponse
Disabling direct streaming when creating the Client, settings.DisableDirectStreaming();
Not using debug mode, ie. settings.EnableDebugMode();

I thought my URL/path may be wrong, but if I run this manually in the Elastic Cloud console I receive a result:

Assistance appreciated, thanks


Could you please post the request and response JSON strings (you find them in the exception.ApiCallDetails object; direct streaming needs to be disabled).

For me it seems like the call itself succeeded (200 response), but something went wrong afterwards.

@flobernd Thanks for your reply!

I can not see a request property but there is a response:

The response is in bytes, which I would expect if it's returning a binary Mapbox vector tile. But I notice HasExpectedContentType is false.

Could my RequestAsync<T> argument be incorrect? I have tried both BytesResponse and DynamicResponse.

I think we are on the right track :slight_smile:

You can provide the expected MIME type like this:

var results = await client.Transport.RequestAsync<BytesResponse>(Elastic.Transport.HttpMethod.GET, path, cancellationToken: ct, requestParameters: new DefaultRequestParameters
	RequestConfiguration = new RequestConfiguration
		Accept = "application/vnd.mapbox-vector-tile"

That worked, I am now exception free! Thanks

I am now having some trouble getting MapLibre to use the data, but I will probably open a new post for that.

MapLibre error:

q {status: 406, statusText: 'Not Acceptable', url: 'http://myUrl?zoom=2&x=0&y=1', body: Blob, message: 'AJAXError: Not Acceptable (406): http://myUrl?zoom=2&x=0&y=1'}

I was able to resolve my data output issue. It was caused by the server. I had the response wrapped in an Ok(result.Body) Action Result.

Returning the BytesResponse in a FileContentResult resolved this issue.


        var result = await _queryHandler.VectorMapQuery(zoom, x, y, ct);
        HttpContext.Response.Headers.Add("Content-Type", "application/vnd.mapbox-vector-tile");
        return File(result.Body, "application/vnd.mapbox-vector-tile");
1 Like