2015-04-14 13 views
8

Zakres:Czy można deserializować pole "ISODate" w MongoDB do JToken (C#)?

Piszę set of tools aby pomóc ludziom uruchomić wspólne operacje na bazach danych MongoDB, oraz „eksportowanie” danych jest jednym z nich.

Obecnie obsługuję pełny eksport JSON i "CSV", ale ten drugi jest trudniejszy.

Narzędzie eksportujące pozwala na "ConfigFile", który określa, które pola będą deserializowane (od BsonDocument), nie dbając o ich typ. Większość typów pracuje obecnie, ale daty "ISO" wciąż sprawiają mi ból głowy.

Dynamiczny Deserializacji

Obecnie jestem powołując się na JObjects obsłużyć parsowania dokumentów "json", podobnie jak to:

 // 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>(); 
       } 
     } 

problem:

ten Kod działa dla wszystkich typów testowanych do tej pory, ale "DateTime". Sposób przechowywania MongoDB jest następujący: "PublicationDate" : ISODate("2014-08-10T00:00:00.000Z"), który całkowicie przerywa moją deserializację.

Próbowałem deserializować go jako "DateTime" i jako "Object", ale oba z nich nie działają. Czy jest jakiś właściwy sposób na zrobienie tego? Jest to w zasadzie wszystko, czego mi brakuje, aby ten "Dynamiczny eksporter" działał.

Dzięki z góry

+0

Ponieważ twoje narzędzia sterują wyjściem JSON, powinieneś być w stanie eksportować daty do JSON w bardziej standardowym formacie; zobacz tutaj, jak to zrobić: http://stackoverflow.com/questions/21466446/handling-mongodbs-isodate-when-attempting-to-parse--serialized-json-string – dbc

+0

Wyrażenie ISODate ("2014-08 -10T00: 00: 00.000Z ") nie jest ważne w Json. Możesz zobaczyć definicję Jsona na http://www.json.org/. Json.Net obsługuje niektóre rozszerzenia, takie jak komentarze, ale daty NIE są w definicji Jsona. Czy masz pełny przykład Json, który chcesz analizować za pomocą Json.NET? –

Odpowiedz

0

try catch może być rozwiązaniem w zły sposób, aby złapać iso datetime? Podobnie jak 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>(); 
      } 
     } 
    } 
} 
Powiązane problemy