2017-06-16 2 views
1

Je voulais désérialiser une chaîne/un objet JSON et l'objet JSON contient des champs date-heure.Désérialisation JSON de Datetime jusqu'à millisecondes dans C#

Ma fonction désérialiser objet JSON est-

public static T ParseJSONToObject<T>(string entity) 
{ 

    return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(entity, new IsoDateTimeConverter{ 
      DateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss.fffffff"        
     }); 

} 

Je voulais que les champs date-heure devraient convertir jusqu'à millisecondes et s'il n'y a pas de valeur en millisecondes, alors il doit montrer de zéro jusqu'à 7 chiffres. Ci-dessous mon JSON object-

[ 
    {"Key": "PendingDate", "Value": "2017-06-15T13:58:00"}, 
    {"Key": "OwnerId", "Value": "xyz"}, 
    {"Key": "ProductList", "Value": "0"}, 
    {"Key": "CreatedDate", "Value": "2017-06-16T09:11:21.678544"}, 
    {"Key": "ModifiedDate", "Value": "2017-06-16T09:11:21.678544"} 
] 

Mais quand je passe cet objet à ma fonction d'analyseur de JSON il ne revient pas les valeurs date-heure dans mon format souhaité.

Mais quand je l'utilise ci-dessous code pour désérialiser une seule chaîne JSON, il est donner output- correct

  var json = "{\"timestamp\":\"2017-06-15T13:58:00.000\"}"; 
      var dict = JsonConvert.DeserializeObject<Dictionary<string,  object>>(json); 
      var r = ((DateTime)dict["timestamp"]).ToString("O"); 

Et la sortie être-

2017-06-15T13:58:00.0000000 

C'est la sortie que je avais besoin mais je ne suis pas sûr de la façon dont j'ai besoin de mettre en œuvre avec ma fonction d'analyseur JSON.

+0

Vous avez un éventail de dictionnaires, pas un seul dictionnaire. De plus, le type 'DateTime' n'a aucun format. C'est une valeur binaire comme 'int' et' double'. Votre * code *, cependant, convertit la date en une * chaîne *. Que demandez-vous après tout cela? –

+0

Code postal qui montre réellement le problème. Ce que vous avez posté suggère que vous avez confondu les représentations de chaînes avec un format DateTime (inexistant). BTW ISO8601 est la valeur par défaut pour JSON.NET. Vous n'avez pas besoin de le spécifier –

Répondre

0

Pas besoin de spécifier DateTimeFormat car le format par défaut lit des millisecondes. Vous perdrez des millisecondes lors de la conversion de l'objet en DateTime. Essayez d'analyser le contenu en type dynamique au lieu du type d'objet, pour éviter les conversions nécessaires au compilateur.

Mise à jour: suppression de la boucle foreach pour afficher la valeur.

/// <summary> 
    /// Specifies the settings on a <see cref="T:Newtonsoft.Json.JsonSerializer" /> object. 
    /// </summary> 
    public class JsonSerializerSettings 
    { 
    ... 
    internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; 

Exemple de code

var data = "[{\"Key\": \"PendingDate\", \"Value\": \"2017-06-15T13:58:00\"}, {\"Key\": \"OwnerId\", \"Value\": \"xyz\"}, {\"Key\": \"ProductList\", \"Value\": \"0\"}, {\"Key\": \"CreatedDate\", \"Value\": \"2017-06-16T09:11:21.678544\"}, {\"Key\": \"ModifiedDate\", \"Value\": \"2017-06-16T09:11:21.678544\"}]"; 

    var deserilizedData = Newtonsoft.Json.JsonConvert.DeserializeObject<OrderDetail[]>(data); 

    var order = deserilizedData.ToDictionary(r => r.Key, r => r.Value); 

    Console.WriteLine("PendingDate: " + order["PendingDate"].ToString("o")); 
    Console.WriteLine("OwnerId: " + order["OwnerId"].ToString()); 
    Console.WriteLine("ProductList: " + order["ProductList"].ToString()); 
    Console.WriteLine("CreatedDate: " + order["CreatedDate"].ToString("o")); 
    Console.WriteLine("ModifiedDate: " + order["ModifiedDate"].ToString("o")); 

de sortie

PendingDate: 2017-06-15T13:58:00.0000000 
OwnerId: xyz 
ProductList: 0 
CreatedDate: 2017-06-16T09:11:21.6785440 
ModifiedDate: 2017-06-16T09:11:21.6785440 

Entité désérialiser

public class OrderDetail 
{ 
    public string Key { get; set; } 

    public dynamic Value { get; set; } 
} 
+0

Salut Kaushal ... merci pour votre réponse mais je ne veux pas utiliser de boucle dans ce cas. J'ai besoin d'une solution directe sans utiliser de boucle. – user3848036

+0

@ user3848036 La boucle est juste pour afficher la valeur. Ce que je voulais dire, c'est que DeserializeObject va analyser et préserver des millisecondes. Vous pourriez les perdre lors de la conversion du type d'objet. S'il vous plaît partager le code comment vous utilisez la valeur analysée. Pour le valider en effet préserver la valeur, vous pouvez mettre un point d'arrêt sur la valeur retournée et vérifier la propriété millisecondes – Kaushal

0

Essayez faire cela.

class Test 
{ 
    public string Key { get; set; } 
    public string Value { get; set; } 
} 

-

DateTime dtParse; 

var deserializeJson = (from d in JsonConvert.DeserializeObject<Test[]>(entity) 
         select new Test() 
         { 
          Key = d.Key, 
          Value = DateTime.TryParse(d.Value, out dtParse) == true ? Convert.ToDateTime(d.Value).ToString("yyyy-MM-ddTHH:mm:ss.fffffff") : d.Value 
         }).ToList(); 
+0

J'ai simplifié ma réponse et je crois que c'est ce que vous cherchez. –

+0

@log merci pour votre réponse.Mais pouvez-vous suggérer n'importe quel moyen avec "IsoDateTimeConverter", parce que je ne peux pas coder en dur les noms de propriété que vous avez fait dans votre code. Parce que j'ai une fonction globale qui fonctionne pour n'importe quel objet et n'importe quel nom de propriété de type Datetime. – user3848036

+0

J'ai vraiment essayé d'utiliser 'IsoDateTimeConverter', mais je ne l'ai pas fait, j'ai fondé la solution alternative, regardez et dites-moi ce que vous en pensez –