Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

JSON...ερώτηση...

Îåêßíçóå áðü ôï ìÝëïò m6s. Τελευταία δημοσίευση από το μέλος m6s στις 30-04-2010, 17:59. Υπάρχουν 8 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  21-04-2010, 18:36 58225

    JSON...ερώτηση...

    Γειά σας, ήθελα να ρωτήσω το εξής σχετικά με το JSON...και αν έχει χρησιμοποιείσει κάποιος την βιβλιοθήκη του Newton
    Απαιτεί για να γίνει το serialization το object να έχει τις μεταβλητές δηλωμένες ώς δημόσιες ( public ) ;
    Παιδευόμουνα με το παρακάτω, αλλά τελικά κατάλαβα ότι έφταιγε οι private δηλώσεις στην κλάση Person. Αν έχεις private μεταβλητές, πώς θα γίνει το serialization!?!?!?!?!?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    public class Person {
    			public string firstName = "Scott";
    			public  string lastName = "Hanselman";
    		}
    
    Person p1 = new Person();
    Person p2 = new Person();
    p1.firstName = "Dimitris";
    p2.lastName = "Mexis";
    
    List<Person> pList = new List<Person>();
    pList.Add(p1); pList.Add(p2);
    
    JsonSerializer serializer = new JsonSerializer();
    SringWriter sw = new StringWriter();
    using ( JsonWriter jsonWriter = new JsonTextWriter(sw) ) {
    serializer.Serialize(sw, pList);
    }
    string output = JavaScriptConvert.SerializeObject(pList);

    Στο deserialize τώρα...αφου το ξεπέρασα το θέμα ( με όχι ωραίο τρόπο..) έχω αυτό :

    IList<Person> persons = JavaScriptConvert.DeserializeObject<List<Person>>(output);

    ...ή...

    using ( StringReader sr = new StringReader(output) ) {
    using ( JsonReader jr = new JsonTextReader(sr) ) {
                            IList<Person> aList = serializer.Deserialize(jr, typeof(List<Person>)) as List<Person>;
                        }
                    }

    Εδώ τώρα δεν καταλαβαίνω γιατί καταλήγω με δυο τρόπους...θέλω να πώ...ταχύτητα ( μια και με ενδιαφέρει για λίστα αντικειμένων )

    Ευχαριστώ!
  •  21-04-2010, 19:34 58226 σε απάντηση της 58225

    Απ: JSON...ερώτηση...

    Η αλήθεια είναι ότι έχω κατεβάσει το library αλλά δεν έχω καν πειραματιστεί μαζί του. Γιατί, όμως, πρέπει να χρησιμοποιήσεις public fields και όχι properties; Απ' ό,τι είδα στο documentation - Serializing and deserializing JSON (Customizing JSON serialization with attributes) - μπορείς να χρησιμοποιήσεις attributes για να πετύχεις customization όσον αφορά στο serialization. Δε σου παίζουν τα παραδείγματα που έχει εκεί;
    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  21-04-2010, 20:13 58229 σε απάντηση της 58226

    Απ: JSON...ερώτηση...

    Την έχω χρησιμοποιησεί χωρίς πρόβλημα, και χωρίς κανένα Attribute στα POCOs.

    Είχα όλα μου τα properties public, και νομίζω πως έτσι πρεπει να είναι. Παίξ3 επίσης και με τους Converters.
    Σου παραθέτω αυτό που είχα κάνει εγώ για Serialize\Deserialize:

     #region Serializing
        public class Serialize
        {
            /// <summary>
            /// Deserialize ένα πίνακα byte[] στο καθορισμένο αντικείμενο.
            /// </summary>
            /// <typeparam name="T">Καθορίζει τον τύπο που θα μετατραπούν τα δεδομένα</typeparam>
            /// <param name="dataObject">Τα δεδομένα σε μορφή byte[] πίνακα.</param>
            /// <returns>Επιστρέφει το άντικείμενο που καθορίσαμε.</returns>
            public static T DeSerializeBytes<T>(byte[] dataObject) where T : class
            {
                string dataString = Encoding.UTF8.GetString(dataObject, 0, dataObject.Length);
                JsonConverter[] converters = new JsonConverter[] { new BinaryConverter() };
                return JsonConvert.DeserializeObject<T>(dataString, converters);
            }
    
            /// <summary>
            /// Serialize ένα αντικείμενο σε μορφή byte[] πίνακα.
            /// </summary>
            /// <typeparam name="T">Καθορίστε τον τύπο του αντικειμένου. Είναι περιττό.</typeparam>
            /// <param name="data">Το αντικείμενο που θέλουμε να μετατραπεί σειριακά. Ο τύπος εντοπίζεται αυτόματα.</param>
            /// <returns>Τον πίνακα byte[].</returns>
            public static byte[] SerializeToBytes<T>(T data) where T : class
            {
               JsonConverter[] converters = new JsonConverter[] { new BinaryConverter() };
                string dataString = JsonConvert.SerializeObject(data, converters);
                return Encoding.UTF8.GetBytes(dataString);
            }
    
            /// <summary>
            /// Serialize ένα αντικείμενο σε μορφή string.
            /// </summary>
            /// <typeparam name="T">>Καθορίστε τον τύπο του αντικειμένου. Είναι περιττό.</typeparam>
            /// <param name="data">Το αντικείμενο που θέλουμε να μετατραπεί σειριακά και επιστρέφετε σε μορφη string.
            /// Ο τύπος εντοπίζεται αυτόματα.</param>
            /// <returns>Το string αντικείμενο.</returns>
            public static string SerializeToString<T>(T data) where T : class
            {
                return JsonConvert.SerializeObject(data);
            }
    
            /// <summary>
            /// Deserialize ένα string στον τύπο του.
            /// </summary>
            /// <typeparam name="T">Ο τύπος των δεδομένων.</typeparam>
            /// <param name="dataString">Το string.</param>
            /// <returns>Τυπος Δεδομένων.</returns>
            public static T DeSerializeFromString<T>(string dataString) where T : class
            {
                 return JsonConvert.DeserializeObject<T>(dataString);
            }
    
            /// <summary>
            /// Αποθήκευση αντικειμένου σε προσωρινό αρχείο σειριακά.
            /// </summary>
            /// <typeparam name="T">Ο τύπος των δεδομένων. Είναι περιττός.</typeparam>
            /// <param name="data">Τα δεδομένα.</param>
            /// <param name="file">Αρχείο. 
            /// <returns>true / false</returns>
            public static bool SerializeToFile<T>(T data, string file) where T : class
            {
                
                 StreamWriter  sw = new StreamWriter(file);
      
                if (sw != null)
                {
                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Converters.Add(new BinaryConverter());
                    using (JsonWriter writer = new JsonTextWriter(sw))
                    {
                        serializer.Serialize(writer, data);
                        return true;
                    }
                }
                return false;
            }
    
            /// <summary>
            /// Deserialize δεδομένα από αρχείο.
            /// </summary>
            /// <typeparam name="T">Ο τύπος των δεδομένων που θα πάρουμε</typeparam>
            /// <returns>true / false</returns>
            public static T DeserializeFromFile<T>(string file) where T : class, new()
            {
                    StreamReader sr = new StreamReader(file);
      
                if (sr != null)
                {
                    string dataString = sr.ReadToEnd();
                    var myObject = JsonConvert.DeserializeObject<T>(dataString);
                    return myObject;
                }
                return new T();
            }
        }
        #endregion
    Έκανα μικρές μετατροπές γιατί χρησιμοποιούσα κανα δύο δικούς μου τύπους αλλα θα παίζει κανονικά. Όπως βλέπεις χρησιμοποιώ τον
    BinaryConverter. Μπορείς ακόμα να κάνεις δουλειά με το JsonWriter και JsonReader. Α! ένα πρόβλημα (κάποιες φορές πετούσε error) που είχα είναι όταν είχα Object με
    Byte[] property serialized Json και επίσης έκανα serialize και το Object (κατάλαβες πιστεύω). Έκανα το byte[] -> string, και άπλα, αυτό είναι και το καλό με το Json.NET


  •  21-04-2010, 20:35 58230 σε απάντηση της 58226

    Απ: JSON...ερώτηση...

    Αυτό το συγκεκριμένο λίνκ δεν το είχα βρεί! Αν το είχα βρεί θα χα γλυτώσει απτο πρώτο κομμάτι της ιστορίας, ΠΩΣ γίνεται το serialization σε λίστα απο αντικείμενα...
    Παρολαυτά, κατέληξα με δυο τρόπους deserialize....και δεν έχω ακόμα καταλάβει...why. Βασικά σήμερα, ξεκίνησα να παίζω με αυτή την βιβλιοθήκη....
    Ευχαριστώ για το link!
  •  21-04-2010, 20:48 58231 σε απάντηση της 58229

    Απ: JSON...ερώτηση...

    Ουόου! (ναι κατάλαβα τι έλεγες... :-) )  Πολύ καλό πρέπει να μελετηθεί...αν και νομίζω ότι αυτό που έκανες είναι ένα υπερσύνολο σε αυτό που λέω.

    Στην SerializeToFile γιατί έβαλες τους writers και δεν χρησιμοποιείσες τον converter ? και μετά να το στείλεις με στο αρχείο...?


    Τέλος, τόσο και σε εσένα όσο και στον Μάρκο, να πώ, ότι δεν θέλω να χω "public properties/variables", διότι δεν είναι αυτό που επιτρέπεται.
    Μιλάμε για αντικείμενα με σχέδιο ανάλογο βασισμένα σε κάποιο Ιnheritance, που θέλω να τα στείλω στον "Ιάσωνα" ( :-) ...καλο; )
    π.χ. να έχει τιμές σε protected μεταβλητές στην πραγματικότητα 2ου, 3ου επιπέδου inheritance...

    Εναλλακτικά....μήπως πρέπει να έχω μήπως να αντικείμενο "μεσάζων"; Που να αναλάβει το ρόλο να κρατάει αυτές τις τιμές; ( oh god noooo! )

  •  21-04-2010, 21:18 58232 σε απάντηση της 58231

    Απ: JSON...ερώτηση...

    Δες το documentation για τα τα property accessors και μίλα με τον JamesNK για ποιο πολλές λεπτομέρειες....

    Στο SerializeToFile, έκανα ότι πρότεινε το documentation για να δουλέψεις με αρχεία, έχει μήνες που το είχα κάνει και δεν θυμάμαι λεπτομέρειες.
    Δες στο documentation θα καταλάβεις κατευθείαν τι κάνουν οι writers....




  •  21-04-2010, 21:20 58233 σε απάντηση της 58232

    Απ: JSON...ερώτηση...

    Οκ, αν και για το θέμα των μεταβλητών που είναι protected/private,  την λύση θα την έδινε το reflection...
  •  21-04-2010, 21:50 58234 σε απάντηση της 58233

    Απ: JSON...ερώτηση...

    Κάτι μου λέει ότι πρέπει να πέσεις στα βαθιά (CustomCreationConverter, και Newtonsoft.Json.Converters Namespace). Αφού το μελετήσεις, κάνε ένα post και για μας...


    Ακόμα κι ένας άνθρωπος μπορεί ν' αλλάξει τον κόσμο. Μη θέλεις να κυβερνήσεις. Απλά δείξε το μονοπάτι κι ο κόσμος θ' ακολουθήσει!!
  •  30-04-2010, 17:59 58456 σε απάντηση της 58234

    Απ: JSON...ερώτηση...

    Φαίνεται οτι η Custom... είναι για >=.net 3.5. Εγώ όπως και να έχει ήθελα κάτι απλό...και παραθέτω τι μανούβρα έκανα...
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    public class Person : IPerson {
    			private string firstName = "Scott";
    			private string lastName = "Hanselman";
    			private int age = 34;
    			public Person() : base() {
    			}
    			public Person( String prsn ) {
    				String[] text = prsn.Split('|');
    				Type t = this.GetType();
    				foreach ( String pair in text ) {
    					String variable = pair.Split(':')[0];
    					String assignment = null;
    					try {
    						assignment = pair.Split(':')[1];
    					} catch ( IndexOutOfRangeException ex ) {
    						return;
    					}
    					foreach ( FieldInfo f in t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) ) {
    						int i = 0;
    						String tmp = "";
    						foreach ( Char v in variable ) {
    							if ( i == 0 ) {
    								tmp += v.ToString().ToUpper();
    							} else
    								tmp += v.ToString();
    							i += 1;
    						}
    						try {
    							t.InvokeMember("set" + tmp, BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, this, new object[] { assignment });
    						} catch ( MissingMethodException ex ) {
    							t.InvokeMember("set" + tmp, BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, this, new object[] { Int32.Parse(assignment) });
    						}
    					}
    				}
    			}
    			public void setFirstName( string name ) {
    				this.firstName = name;
    			}
    			public void setLastName( string name ) {
    				this.lastName = name;
    			}
    			public void setAge( int ag ) {
    				this.age= ag;
    			}
    			public String getFirstName() {
    				return this.firstName;
    			}
    			public String getLastName() {
    				return this.lastName;
    			}
    
    			public String ToString() {
    				StringBuilder info = new StringBuilder();
    				Type t = this.GetType();
    				foreach ( FieldInfo f in t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) ) {
    					info.Append(f.Name + ":" + f.GetValue(this)+ "|" );
    				}
    				return info.ToString();
    			}
    		}

    Κρατάω όλες τις τιμές των "Fields" σε ένα ζεύγος τιμών χωρισμένων με '|'. Και όταν θέλω να δημιουργήσω καλώ την Person με όρισμα το παλιότερο Person.
    Κάπως έτσι :
    Person p2 = new Person();
    p2.setFirstName("Nick");
    p2.setLastName("TheGreek");

    Person p3 = new Person(p2.ToString());

    Ετσι, και δεν χάνω την αρχιτεκτονική της κλάσσης και επαναδημιουργώ το αντικείμενο με τις τιμές που είχε παλιότερα...αποθηκευμένα σε βάση.
    Δεν ξέρω, αλλά αυτό δεν θα έπρεπε να το κάνει το JSON? Αν μου ξέφυγε κάτι και μπορεί να το κάνει το JSON ( ακόμα και με το JavaSerializer του System.Web πήγα, αλλά πεδεύτικα με converters κλπ....τελικά αναρωτιέμαι αν άξιζε; ) μπορώ να το ξανακάνω σε JSON ή σε κάτι άλλο.

    Επίσης, το συγκεκριμένο snippet έχει 2 προβλήματα όμως που έχουν να κάνουν με τα Exception που μαζεύω.
     1. Στην Invoke 28-31, επειδή έχω διάφορετικούς τύπους μεταβλητές, παίζω με τα exception, δεν θα έπρεπε όμως.
     2. Τo IndexOutOfRange δεν έχω καταλάβει γιατί το πετάει!

    Αν έχει κάποιος όρεξη να το εμπλουτίσει, είμαι όλος αυτιά! :-)

    Καλό ΣΚ.

    Να σημειώσω ότι αν θυμίζει Java setter/getter....δεν έχετε άδικο! Big Smile
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems