2

I have some telemetry data that was stored in a text field as JSON. I'm attempting to reverse-engineer POCOs to seamlessly extract and present that data without having to do any post-processing ForEach loops.

When I attempt to manually parse the JSON string in the data field, it works. When I am selecting via ORMLite, it comes back with the default object. What am I missing?

Works

string x = "{\"alive\":true,\"paperStatus\":\"0:NoIssue\"}";
var telemetry = JsonSerializer.DeserializeFromString<KioskTelemetryData>(x);

Doesn't populate Data field

var exp = Db.From<KioskTelemetryLog>()
                    .Where(q => q.Identifier == request.Identifier)
                    .OrderByDescending(q => q.Timestamp);

var data = Db.Select(exp);

Here is what the data records look like:

Id  Identifier  IsCurrent   RedemptionCenterId  Timestamp               Status  Data
1   XXX        0            NULL                2015-11-24 11:10:53.527 1       {"alive":true,"paperStatus":"1:LowPaper"}
2   XXX        0            NULL                2015-12-01 12:16:56.653 0       {"alive":true,"paperStatus":"0:NoIssue"}    
1   XXX        1            NULL                2015-12-01 18:32:11.337 2       {"alive":false}

And here are the POCOs:

[Alias("TelemetryLog")]
public class KioskTelemetryLog
{
    public long Id { get; set; }

    public string Identifier { get; set; }

    public bool IsCurrent { get; set; }

    public int? RedemptionCenterId { get; set; }

    public DateTime Timestamp { get; set; }

    // 0 = okay, 1 = warning, 2 = error
    public sbyte Status { get; set; }

    public KioskTelemetryData Data { get; set; }
}

public class KioskTelemetryData
{
    public bool Alive { get; set; }
    public string PaperStatus { get; set; }
}
jklemmack
  • 3,518
  • 3
  • 30
  • 56

1 Answers1

2

The default complex type serializer for OrmLite is the JSV Format (except for PostgreSQL which uses JSON). OrmLite does support pluggable text serializers, e.g. you can change SQL Server to use JSON for serializing complex types with:

SqlServerDialect.Provider.StringSerializer = new JsonStringSerializer();

If it's not serializing correctly it's like a serialization error, you can try enable logging for more info about the error, e.g:

LogManager.LogFactory = new ConsoleLogFactory(debugEnabled:true); 
mythz
  • 141,670
  • 29
  • 246
  • 390
  • Ung - totally missed that in the [docs here] (https://github.com/ServiceStack/ServiceStack.OrmLite#pluggable-complex-type-serializers). Is it possible to override the behavior on a query basis like you can with the JsonSerializer? – jklemmack Feb 03 '16 at 20:25
  • @jklemmack no, you could temporarily override it and revert it in a finally statement but that's not threadsafe. Another approach is to declare the property as a string then have a method like `KioskTelemetryData GetData()` which returns the deserialized version. – mythz Feb 03 '16 at 20:40
  • Ah - I really like the extra method approach to do the deserialization, since the same telemetry table holds data for several different categories of devices. And I'd probably implement it as read-only properties based on the type. That lets me re-translate the whole POCO to JSON and feed it to the dashboard website. – jklemmack Feb 03 '16 at 21:23