2017-02-08 10 views
3

Служба REST, которую я использую, RSA Archer ожидает целочисленный ключ, что означает, что я просто не могу вложить объекты [Serializable], а затем JsonUtility.ToJson(), чтобы создать сериализованную строку JSON. Я думал, что нашел решение для создания объекта Dictionary, а затем использовать ISerializationCallbackReceiver для обработки только словарной части вложенной структуры, но приведенный ниже код просто игнорирует эту часть вложенного объекта и не сериализует Dictionary. Есть ли у кого-нибудь мысли о наилучшем подходе к этому?Unity Serializing Nested Dictionary для JSON

Ожидаемый результат:

{"Content": {"LevelId": 10,"FieldContents": {"47": {"Type": 1, "Value": "me", "FieldId": 47}}}} 

Структура объекта:

[Serializable] 
public class Record 
{ 
    public Content Content; 
} 

[Serializable] 
public class Content 
{ 
    public int LevelId; 
    public FieldContents FieldContents; 
} 

public class FieldContents : ISerializationCallbackReceiver 
{ 
    public Dictionary<string, FieldValue> FieldValues; 

    public List<string> dicKeys; 
    public List<FieldValue> dicVals; 

    public void OnBeforeSerialize() 
    { 
     dicKeys.Clear(); 
     dicVals.Clear(); 
     foreach (var kvp in FieldValues) { 
      dicKeys.Add (kvp.Key); 
      dicVals.Add (kvp.Value); 
     } 
    } 

    public void OnAfterDeserialize() 
    { 
     FieldValues = new Dictionary<string, FieldValue>(); 
     for (int i = 0; i < Math.Min (dicKeys.Count, dicVals.Count); i++) { 
      FieldValues.Add (dicKeys [i], dicVals [i]); 
     } 
    } 
} 

[Serializable] 
public class FieldValue 
{ 
    public int Type; 
    public string Value; 
    public int FieldId; 
} 

JSONUtility и Инстанцирование:

Record newRecord = new Record() { Content = new Content() { 
       LevelId = 10, 
       FieldContents = new FieldContents() { FieldValues = new Dictionary<string, FieldValue>() { { 
          "47", 
          new FieldValue() { 
           Type = 1, 
           Value = "me", 
           FieldId = 47 
          } 
         } 
        } 
       } 
      } 
     }; 
Debug.Log (JsonUtility.ToJson (newRecord)); 
+1

Unity 'JsonUtility' делает ** не ** поддерживает словарь. – Programmer

+0

@Programmer, поэтому я пытался использовать 'ISerializationCallbackReceiver'. Будет ли более подходящей структура данных? – hotshotiguana

+0

Извините. На самом деле это не помогает. Вероятно, вы должны использовать платный плагин Json, который поддерживает словарь. Это моя рекомендация в вашем случае. – Programmer

ответ

0

JsonUtility это самый быстрый способ использовать jsons, поскольку это не создает почти любой GC. Проблема в том, что она не очень гибкая, потому что вам нужно заранее знать структуру данных, и она не может быть мутирована, так как ей нужен класс.

Если вам нужно использовать Jsons как словари можно использовать либо MiniJSON (только правый Clic и Сохранить как ...) или JSONObject, оба свободны и работать в любой платформе Altough они намного медленнее, чем JsonUtilty, так что если вы разбираете большие jsons или должны делать это много раз, в то время как производительность имеет значение, тогда это не будет жидким.

Я лично использовал оба варианта, и они великолепны, MiniJSON немного проще в использовании, в то время как JSONObject является немного более мощным, но также немного сложнее начать.

EDIT:

Как уже упоминалось в одном из комментариев можно также использовать Newtonsoft, я думаю, что это быстрее, чем minijson и JSONObject, но может быть излишним, если вы не делаете много вещей с jsons.

+0

Спасибо @Juan. Я, конечно, не против сторонних библиотек, но когда я использовал LitJSON для этого, я столкнулся со многими проблемами, чтобы заставить его работать с Hololens, следовательно, отключение JsonUtility. Я проведу эти другие библиотеки и посмотрю, как они это делают. – hotshotiguana

+0

Я рекомендую вам minijson, если вам не нужно разбирать большие jsons, это всего лишь скрипт, и он очень прост в использовании. Google и Facebook используют его в своих sdks для единства –