不正确的json.net序列化

时间:2018-11-19 23:25:02

标签: generics dynamic json.net dapper

我在使用NewtonSoft JsonConvert序列化对象图时遇到麻烦。 Dapper可以通过两种方式工作:Query(string sql[, object args])方法可以返回IEnumerable<dynamic>或通用Query<T>(string sql[, object args])方法可以返回IEnumerable<T>

当我输入结果时,它会起作用:

stringifiedDynamicData
[{"Record_Key":2,"Factory_Key":7,"EnteredAt":"2018-11-20T09:03:03.374",...}]

当我为结果指定类型时,结果如下:

stringifiedTypedData
[{}]

这是产生以上代码的代码。

IDbConnection syb = new OdbcConnection(connectionstring);
var sql = System.IO.File.ReadAllText("./powerbi.sybase");
var typedData = syb.Query<Status>(sql);
var stringifiedTypedData = JsonConvert.SerializeObject(typedData); 
Console.WriteLine("stringifiedTypedData");
Console.WriteLine(stringifiedTypedData);
var dynamicData = syb.Query(sql);
var stringifiedDynamicData = JsonConvert.SerializeObject(dynamicData);
Console.WriteLine("stringifiedDynamicData");
Console.WriteLine(stringifiedDynamicData);      

对变量typedData的调试检查显示,像预期的那样,具有一个元素的Status对象的集合。这些字段具有期望值,所以当JsonConvert.Deserialize(typedData)返回[{}]

时有点惊讶

添加此

  var foo = new {
    A = "wibble", B = 6
  };
  IEnumerable<object> bar = from x in new object[] { foo } select x;
  var quux = JsonConvert.SerializeObject(bar);
  Console.WriteLine("quux");
  Console.WriteLine(quux);

产生预期的结果

quux
[{"A":"wibble","B":6}]

表示数据就是问题。 所以这不是某种配置问题。

Status类具有这种形式。

public class Status
{
  float AdtechAmt { get; set; } = -1;
  float AssemblyError { get; set; } = -1;
  string CutToFinish_Avg { get; set; } = "-1";
  ...
}

我刚刚添加了默认值,以查看是否有区别(否)。

我认为我使用Typescript的时间已经太久了,这让我感到这些属性不是公开的。

1 个答案:

答案 0 :(得分:2)

从根本上讲这是Bonehead程序员错误,带有Typescript的错误。

C#和Typescript都支持不带修饰符的属性。但是,尽管未修改的Typescript属性默认为public,但在C#中它们默认为protected。由于不需要类具有任何公共属性,因此不会发生静态编译器错误。

Dapper使用反射并可以查看受保护的成员,并将其成功匹配到数据集字段,然后填充它们。 Dapper成功使用该类来键入结果,这进一步掩盖了将属性公开的失败。

第一个可见的效果是无属性序列化。毫无例外的原因是,所有对象(在本例中为一行)均已成功序列化,并且所有公共属性(无)均以JSON字符串表示。