IDs are objects in the C# SDK, so JSON libraries like Newtonsoft won't automatically serialize them to strings by default. It will try to serialize the public properties of the object as a JSON object, but because ID has no public properties, you get the empty object ("{}").
You have a few options - you can either implement your own custom JsonConverter to handle IDs correctly:
public class GeotabIdConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
// Id implements a .ToString() that returns the actual ID value
writer.WriteValue(value?.ToString());
}
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
var value = reader.Value?.ToString();
return string.IsNullOrEmpty(value) ? Id.Null : Id.Create(value);
}
public override bool CanConvert(Type objectType)
{
return objectType.Namespace?.Contains("Geotab") == true &&
objectType.Name.Contains("Id", StringComparison.OrdinalIgnoreCase);
}
}
// Then how you would use it
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore,
Converters = { new GeotabIdConverter() }
}
return JsonConvert.SerializeObject(value, settings);That outputs the following:
{
"FromDate": "2025-11-20T15:05:08.9504469Z",
"ToDate": "2025-11-20T15:05:08.9504904Z",
"UserSearch": {
"Id": "TestId"
}
}Or, if you know you're writing Geotab objects and want it formatted in the same way the SDK does, you can use the GeotabJsonSerializer directly:
// You'll need this using statement
using Geotab.Checkmate.Serialization;
// ... rest of your code
return GeotabJsonSerializer.Instance.ObjectToJson(value);Which results in this output with slightly different formatting:
{
"fromDate": "2025-11-20T15:05:08.950Z",
"toDate": "2025-11-20T15:05:08.950Z",
"userSearch": {
"id": "TestId"
}
}