【发布时间】:2018-02-01 13:33:33
【问题描述】:
我尝试在数据库 SQL Server 2012 中使用 Newtonsoft.Json 版本“Newtonsoft.Json.10.0.3”将 DataTable 对象序列化为 Json。
该表有一个类型为“geography”的列,其中包含SqlGeography 类型的实例。
用于生成json的代码:
public string SerializeToJson()
{
var connstring1 ="Data Source=server1;Initial Catalog=database1;user=xxx;password=yyy";
var sql = "SELECT * FROM table_1 "; //table_1 has a column of type geography
using (var c1 = new SqlConnection(connstring1))
{
c1.Open();
var da = new SqlDataAdapter()
{
SelectCommand = new SqlCommand(sql, c1)
};
DataSet ds1 = new DataSet("table");
da.Fill(ds1, "table");
var dt = ds1.Tables[0];
//serialize to Json
try
{
var options = new JsonSerializerSettings
{
Formatting = Formatting.None
};
//this line fire exception for geography type
var json = JsonConvert.SerializeObject(dt, options);
return json;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
我已经从 sql 2012 的功能包中安装了程序集“Microsoft.SqlServer.Types”
我创建了一个完整的 C# 程序(独立于 sql server 安装),使用带有 SqlGeography 列的数据表来显示问题 Try it
我得到错误:
Newtonsoft.Json.JsonSerializationException:从“System.Data.SqlTypes.SqlDouble”上的“Value”获取值时出错。 --->
System.Data.SqlTypes.SqlNullValueException:数据为空。 不能对 Null 值调用此方法或属性。 在 System.Data.SqlTypes.SqlDouble.get_Value() 在 GetValue(对象) 在 Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object 目标)
我联系了https://github.com/JamesNK/Newtonsoft.Json/issues/993,但无济于事。
任何解决问题的帮助。
编辑:
基于@dbc cmets,我提供了用于生成json的完整源代码。
完整的错误信息是:
Newtonsoft.Json.JsonSerializationException:从“System.Data.SqlTypes.SqlDouble”上的“Value”获取值时出错。 ---> >System.Data.SqlTypes.SqlNullValueException:数据为空。不能对 Null 值调用此方法或属性。 在 System.Data.SqlTypes.SqlDouble.get_Value() 在 GetValue(对象) 在 Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object 目标)
--- 内部异常堆栈跟踪结束 --- 在 Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object 目标)
在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue( JsonWriter writer,Object 值,JsonContract valueContract,JsonProperty 成员 , JsonContainerContract containerContract, JsonProperty containerProperty) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue( JsonWriter writer,Object 值,JsonContract valueContract,JsonProperty 成员 , JsonContainerContract containerContract, JsonProperty containerProperty) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType) 在 Newtonsoft.Json.Serialization.JsonSerializerProxy.SerializeInternal(JsonWriter jsonWriter,对象值,类型 rootType) 在 Newtonsoft.Json.Converters.DataTableConverter.WriteJson(JsonWriter 作家, 对象值,JsonSerializer 序列化器) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeConver table(JsonWriter writer, JsonConverter转换器, Object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue( JsonWriter writer,Object 值,JsonContract valueContract,JsonProperty 成员 , JsonContainerContract containerContract, JsonProperty containerProperty) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType) 在 Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter,对象值,类型 objectType) 在 Newtonsoft.Json.JsonConvert.SerializeObjectInternal(对象值,类型类型,JsonSerializer jsonSerializer) 在 Newtonsoft.Json.JsonConvert.SerializeObject(对象值,JsonSerializerSettings 设置) 在 F:\JsonTester.cs:line 104 中的 JsonTester.SerializeToJson() 处
编辑2:
我按照@dbc 的描述启用了跟踪,并获得以下日志:
2017-08-24T19:45:31.941 Info 开始使用转换器 Newtonsoft.Json.Converters.DataTableConverter 序列化 System.Data.DataTable。路径''。
2017-08-24T19:45:31.972 信息开始序列化 Microsoft.SqlServer.Types.SqlGeography。路径“[0].f1”。
2017-08-24T19:45:32.003 Info 开始序列化 System.Data.SqlTypes.SqlInt32.Path '[0].f1.STSrid'。
2017-08-24T19:45:32.003 信息已完成序列化 System.Data.SqlTypes.SqlInt32。路径“[0].f1.STSrid”。
2017-08-24T19:45:32.003 信息开始序列化 System.Data.SqlTypes.SqlDouble。路径'[0].f1.Lat'。
2017-08-24T19:45:32.003 信息已完成序列化 System.Data.SqlTypes.SqlDouble。路径'[0].f1.Lat'。
2017-08-24T19:45:32.003 信息开始序列化 System.Data.SqlTypes.SqlDouble。路径“[0].f1.Long”。
2017-08-24T19:45:32.003 信息已完成序列化 System.Data.SqlTypes.SqlDouble。路径“[0].f1.Long”。
2017-08-24T19:45:32.003 信息开始序列化 System.Data.SqlTypes.SqlDouble。路径“[0].f1.Z”。
2017-08-24T19:45:32.003 序列化 System.Data.SqlTypes.SqlDouble 时出错。从“System.Data.SqlTypes.SqlDouble”上的“Value”获取值时出错。
2017-08-24T19:45:32.003 错误序列化 System.Data.DataTable 时出错。从“System.Data.SqlTypes.SqlDouble”上的“Value”获取值时出错。
【问题讨论】:
-
1) 有什么方法可以提供minimal reproducible example? 2) 我没有安装 SQL 服务器,所以我无法对此进行测试,但是如果您使用来自JSON.net serialize directly from oledbconnection 的
DataReaderConverter从command.ExecuteReader()返回的IDataReader直接序列化会发生什么? -
而且,如果您不能提供minimal reproducible example,您能否至少在edit 中包含异常的完整
ToString()输出,包括异常类型、消息、回溯和内部异常? -
谢谢@dbc。我用完整的代码和错误消息更新了我的问题。 IDatareader 示例很棒,但只提供序列化,我需要反序列化 json。你能给我提供一个 IDataReader 的反序列化示例吗:)。
-
1) 你能像here 那样启用跟踪并让我们知道日志显示的内容吗?看起来 Json.NET 无法序列化
SqlGeometry类型的实例,但我想确认一下。 2) 要从SqlCommand获取数据读取器,请参阅Retrieving Data Using a DataReader。 -
@dbc,我使用带有 SqlGeography 列的数据表创建了一个完整的 C# 程序(独立于 sql server 安装)来显示问题。可以在线试用dotnetfiddle.net/8MMQOW
标签: c# sql-server json geolocation json.net