首页 > 解决方案 > 具有空值的 Newtonsoft.Json.JsonConvert.DeserializeObject 问题

问题描述

我正在使用SqlBulkCopy来自 C# 和 SQL Server 2016 的 json 数据。

原始字符串是:"1979-09-30T23:00:00.000+0000"

但是当使用 复制到 SQL Server 表中SqlBulkCopy时,字符串变为 "01/10/1979 00:00:00"

varchar(100)用作此列的数据类型。

我尝试使用date,datetimedatetimeoffset数据类型,但每次都遇到转换错误。

create table Employees(
matricule  nvarchar(20),
pname  nvarchar(100),
birthdate  varchar(100),
hiredate varchar(100))

-- 我尝试使用日期、日期时间和日期时间偏移数据类型,但每次都遇到转换错误。)

怎么做才能保存原始数据?

经过分析,我发现问题根源 Json 在日期字段中有空值日期是 json 是这样的

“字段日期名称”:空

json 序列化程序在该字段中出现错误

public static void BulkCopy(DataTable myDataTable)
{           
    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["2"].ConnectionString))
    {
        connection.Open();

        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
        {
            foreach (DataColumn c in myDataTable.Columns)
                bulkCopy.ColumnMappings.Add(c.ColumnName, c.ColumnName);

            bulkCopy.DestinationTableName = myDataTable.TableName;

            try
            {
                bulkCopy.WriteToServer(myDataTable);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);                        
            }
        }
    }
}

这是调用它的方法

public static void Employee()
        {
            try
            {                
                DataTable MyTable = Clapi.GetApiData(ConfigurationManager.AppSettings.Get("api_employe"), "imp_Employees").GetAwaiter().GetResult();
                log.Info(String.Format("Table: {0} Count {1}", MyTable.TableName, MyTable.Rows.Count));
                Cldb.BulkCopy(MyTable);
            }
            catch(Exception ex)
            {
                log.Error(ex.Message);
            }
        }

//这里是GetApiData

public static async Task<DataTable> GetApiData(string Url ,string TableName)
        {
            try
            {
                var client = new HttpClient();
                var request = new HttpRequestMessage(HttpMethod.Get, Url);
                var response = await client.SendAsync(request);
                var contents = response.Content.ReadAsStringAsync().Result;
                var Mytable = JsonConvert.DeserializeObject<DataTable>(contents);
                Mytable.TableName = TableName;
                return Mytable;
            }
            catch(Exception ex)
            {
                log.Error("GetApiData; url="+Url+";TableName:"+TableName+ex.Message);
                return null;
            }
        }

json数据

[{“矩阵”:“0009”,“pname”:“xxxx”,
“生日”:“1961-02-25T23:00:00.000+0000”,“雇用日期”:“1976-02-14T23:00:00.000 +0000"
}]

批量复制到 sql server 后,这两个日期变为

“1961-02-25T23:00:00.000+0000”变为 02/26/1961 00:00:00
“1976-02-14T23:00:00.000+0000”变为 15/02/1976 00:00:00

我也尝试过设置,但仍然出现错误

NullValueHandling = NullValueHandling.Ignore

标签: c#sql-serverdate-formattingsqlbulkcopy

解决方案


使用JsonSerializationSettingswith DateTimeZoneHandling = DateTimeZoneHandling.Utcthen 将表日期列声明为datetime数据类型。

public static async Task<DataTable> GetApiData(string Url, string TableName)
{
    try
    {
        var client = new HttpClient();
        var request = new HttpRequestMessage(HttpMethod.Get, Url);
        var response = await client.SendAsync(request);
        var contents = response.Content.ReadAsStringAsync().Result;
        var settings = new JsonSerializerSettings
        {
            DateTimeZoneHandling = DateTimeZoneHandling.Utc
        };
        var Mytable = JsonConvert.DeserializeObject<DataTable>(contents, settings);
        Mytable.TableName = TableName;
        return Mytable;
    }
    catch (Exception ex)
    {
        log.Error("GetApiData; url=" + Url + ";TableName:" + TableName + ex.Message);
        return null;
    }
}

推荐阅读