2015-04-14 11 views
8

Ambito:E 'possibile deserializzare un campo "ISODate" di MongoDB su un JToken (C#)?

Sto scrivendo un set of tools per aiutare le persone eseguire operazioni comuni sul loro database MongoDB, e "esportare" i dati è uno di loro.

Attualmente supporto l'esportazione JSON completa e "CSV", ma quest'ultima è molto più complessa.

Lo strumento di esportazione consente un "ConfigFile" che specifica quali campi verranno deserializzati (da un BsonDocument), senza preoccuparsi del loro tipo. La maggior parte dei tipi sta funzionando, ma le date "ISO" mi stanno ancora facendo venire il mal di testa.

dinamica deserializzazione

Attualmente sto contando su JObjects per gestire il parsing dei documenti "JSON", proprio come questo:

 // Json Writer Settings - To avoid problems with 10Gen types 
     var jsonSettings = new JsonWriterSettings() { OutputMode = JsonOutputMode.Strict }; 

     // Mapping string to a dynamic json object 
     JObject mappedJson = JObject.Parse (jsonObject.ToJson (jsonSettings)); 

     // Trying to extract property values out of the object 
     foreach (Field field in _configuration.Fields) 
     { 
       // Checking for JToken Type 
       JTokenType objType = fieldData.Type; 

       // Sanity Check for NULL Values of properties that do exist 
       if (objType == JTokenType.Null) 
       { 
        fieldValue = String.Empty; 
       } 
       else if (objType == JTokenType.Array) // Checking for Arrays (that need to be serialized differently) 
       { 
        String[] valuesArray = fieldData.Select (t => t.Value<String>().Replace (_configuration.ListDelimiter, String.Empty) 
                        .Replace (_configuration.Delimiter, String.Empty)).ToArray(); 

        fieldValue = String.Join (_configuration.ListDelimiter, valuesArray); 
       } 
       else if (objType == JTokenType.Object && field.Name.Equals ("_id")) // Checking for specific MongoDB "_id" situation 
       { 
        fieldValue = fieldData.ToObject<String>(); // Value<ObjectId>().ToString(); 
       } 
       else 
       { 
        // Reaching Attribute Value as "String" (if nothing else worked) 
        fieldValue = fieldData.Value<String>(); 
       } 
     } 

Il problema:

Questo il codice funziona per tutti i tipi che ho provato finora, ma "DateTime". Il modo in cui negozi MongoDB è il seguente: "PublicationDate" : ISODate("2014-08-10T00:00:00.000Z"), che interrompe completamente la mia deserializzazione.

Ho provato a deserializzare come "DateTime" e come "Object", ma entrambi non funzionano. C'è un modo corretto per farlo? Questo è fondamentalmente tutto ciò che mi manca per far funzionare questo "Dynamic Exporter".

Grazie in anticipo

+0

Poiché gli strumenti controllano l'output JSON, dovresti essere in grado di esportare le date in JSON in un formato più standard; vedere qui come farlo: http://stackoverflow.com/questions/21466446/handling-mongodbs-isodate-when-attempting-to-parse-a-serialized-json-string – dbc

+0

L'espressione ISODate ("2014-08 -10T00: 00: 00.000Z ") non è valido in Json. Puoi vedere la definizione di Json su http://www.json.org/. Json.Net supporta alcune estensioni, come i commenti, ma le date NON sono nella definizione di Json. Hai un esempio completo del Json che vuoi analizzare con Json.NET? –

risposta

0

try catch può essere una soluzione in un brutto modo per catturare iso datetime? Mi piace JTokenType.Date.

using System.Globalization; 

public static void ParseMongoDBISODate() 
{ 
    // Json Writer Settings - To avoid problems with 10Gen types 
    var jsonSettings = new JsonWriterSettings() { OutputMode = JsonOutputMode.Strict }; 

    // Mapping string to a dynamic json object 
    JObject mappedJson = JObject.Parse(jsonObject.ToJson(jsonSettings)); 

    // Trying to extract property values out of the object 
    foreach (Field field in _configuration.Fields) 
    { 
     // Checking for JToken Type 
     JTokenType objType = fieldData.Type; 

     // Sanity Check for NULL Values of properties that do exist 
     if (objType == JTokenType.Null) 
     { 
      fieldValue = String.Empty; 
     } 
     // Checking for Arrays (that need to be serialized differently) 
     else if (objType == JTokenType.Array) 
     { 
      String[] valuesArray = fieldData.Select(t => t.Value<String>().Replace(_configuration.ListDelimiter, String.Empty).Replace(_configuration.Delimiter, String.Empty)).ToArray(); 

      fieldValue = String.Join(_configuration.ListDelimiter, valuesArray); 
     } 
     // Checking for specific MongoDB "_id" situation 
     else if (objType == JTokenType.Object && field.Name.Equals("_id")) 
     { 
      fieldValue = fieldData.ToObject<String>(); // Value<ObjectId>().ToString(); 
     } 
     else 
     { 
      try // it's a bad way but you can set fieldValue as a DateTime 
      { 
       //JTokenType.Date 
       DateTime mongoDBISODate = DateTime.Parse(fieldData.Value<String>(), null, DateTimeStyles.RoundtripKind); 
       fieldValue = mongoDBISODate; 
      } 
      catch (Exception) 
      { 
       // Reaching Attribute Value as "String" (if nothing else worked) 
       fieldValue = fieldData.Value<String>(); 
      } 
     } 
    } 
} 
Problemi correlati