Newtonsoft. Json .JsonConvert.DeserializeObject проблема с нулевыми значениями - PullRequest
0 голосов
/ 07 мая 2020

Я использую SqlBulkCopy из json данных, используя C# и SQL Server 2016.

Исходная строка: "1979-09-30T23:00:00.000+0000"

Но при копировании в таблица сервера SQL с использованием SqlBulkCopy, строка становится "01/10/1979 00:00:00"

Я использую varchar(100) в качестве типа данных для этого столбца.

Я пробовал с date, datetime и datetimeoffset, но каждый раз я получал ошибки преобразования.

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

- Я пробовал использовать типы данных date, datetime и datetimeoffset, но каждый раз получал ошибки преобразования. )

Как сделать, чтобы сохранить исходные данные?

После анализа я обнаружил проблему root Json имеет нулевые значения в поле даты, дата json вот так

"field_date_name": null

сериализатор 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);                        
            }
        }
    }
}

Вот вызов метода it

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 data

[{"matricule": "0009", "pname" : «xxxx»,
«дата рождения»: «1961-02-25T23: 00: 00.000 + 0000», «нанятый»: «1976-02-14T23: 00: 00.000 + 0000»
}]

После массового копирования на сервер sql эти 2 даты становятся

"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

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Используйте JsonSerializationSettings с DateTimeZoneHandling = DateTimeZoneHandling.Utc, затем объявите столбцы даты таблицы как тип данных 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;
    }
}
0 голосов
/ 07 мая 2020

вы, вероятно, используете в своем коде DateTimeOffset.

DateTimeOffset = DateTime + Offset (от UT C)

разница, вероятно, является причиной смещения между клиентом и сервером (две разные зоны)

если вы используете DateTime, у вас не будет этой проблемы.

1) сначала попробуйте отладить свой код, чтобы увидеть, совпадает ли значение, которое будет сохранено в базе данных, с сохраненным значением.

2) Таким образом, ваши данные уже представляют местную дату и время клиента. Просто приведите его к DateTime, и вы получите локальную дату и время клиента.

подробнее ссылка

...