Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Solved
  • Unsolved
  • Users
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (Darkly)
  • No Skin
Collapse
brainCloud Forums
  1. Home
  2. APIs
  3. Difficulty parsing JSON response in Unity

Difficulty parsing JSON response in Unity

Scheduled Pinned Locked Moved APIs
unityjsonjsonutility
2 Posts 2 Posters 1.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Nick Novikov
    wrote on last edited by
    #1

    I'm purchasing some item using the following code (example from BrainCloud API reference):

    _bc.UserItemsService.PurchaseUserItem(defId, quantity, shopId, includeDef, successCallback, failureCallback);
    

    I get the following JSON in response (example from BrainCloud API reference):

    {
      "data": {
        "items": {
          "8e12e907-3f54-4971-b84a-b685ce50b684": {
            "itemId": "8e12e907-3f54-4971-b84a-b685ce50b684",
            "defId": "boost_rapidfire",
            "quantity": 1,
            "usesLeft": null,
            "coolDownStart": -1,
            "recoveryStart": -1,
            "itemData": {},
            "giftedTo": null,
            "giftedFrom": null,
            "blockId": null,
            "createdAt": 1566850132554,
            "updatedAt": 1566850132554,
            "version": 1,
            "maxUses": null,
            "coolDownUntil": -1,
            "recoveryUntil": -1,
            "itemDef": {
              "defId": "boost_rapidfire",
              "name": "Rapid Fire",
              "desc": "Rapid fire for the next match.",
              "type": "ITEM",
              "category": "boost",
              "tags": null,
              "buyPrice": {
                "coins": 200
              },
              "sellPrice": {},
              "image": null,
              "resourceGroup": null,
              "resourceTag": null,
              "meta": {},
              "pState": "PUBLISHED",
              "publishedAt": 1566850042148,
              "stackable": false,
              "consumable": false,
              "uses": null,
              "coolDownSecs": 0,
              "recoverySecs": 0,
              "activatable": true,
              "statusName": "boosted",
              "activeSecs": 900000,
              "tradable": false,
              "blockchain": false,
              "blockchainDefId": null
            }
          }
        },
        "currencySpent": {
          "coins": 200
        },
        "currencyBalances": {
          "createdAt": 1566850026783,
          "currencyMap": {
            "coins": {
              "consumed": 200,
              "balance": 2999800,
              "purchased": 0,
              "awarded": 3000000
            }
          },
          "playerId": "55ffc16e-f92b-44f3-98b0-68a7a4f24106",
          "updatedAt": 1566850132552
        }
      },
      "status": 200
    }
    

    Basically we have the following hierarchy of JSON keys: data.items["8e12e907-3f54-4971-b84a-b685ce50b684"].itemId and so on.
    The problem with this response is it uses UUID 8e12e907-3f54-4971-b84a-b685ce50b684 as a JSON key which is obviously not known in advance. Hence, I cannot use built-in Unity's JsonUtility library to map this JSON response to a C# object, like this:

    [System.Serializable]
    private class PurchaseUserItemSuccessResponse {
        public Data data;
        [System.Serializable]
        public class Data {
            public Items items;
            [System.Serializable]
            public class Items {
                // The problem:
                // Can't define specific items here
                // because their keys are not known in advance
            }
        }
    }
    

    Of course, I can try to use some preprocessing tricks or to utilize external JSON library to overcome the issue, but still, using dynamic keys in JSON response for me looks like a bad practice because it creates unnecessary obstacles. It would be simpler to expect solid JSON keys structure. As a developer, for this specific case, I would have liked to see results as a simple array, like this:

    {
      "data": {
        "items": [
            "itemId": "8e12e907-3f54-4971-b84a-b685ce50b684",
            "defId": "boost_rapidfire",
            "quantity": 1,
            "usesLeft": null,
            "coolDownStart": -1,
            "recoveryStart": -1,
            "itemData": {},
            "giftedTo": null,
            "giftedFrom": null,
            "blockId": null,
            "createdAt": 1566850132554,
            "updatedAt": 1566850132554,
            "version": 1,
            "maxUses": null,
            "coolDownUntil": -1,
            "recoveryUntil": -1,
            "itemDef": {
              "defId": "boost_rapidfire",
              "name": "Rapid Fire",
              "desc": "Rapid fire for the next match.",
              "type": "ITEM",
              "category": "boost",
              "tags": null,
              "buyPrice": {
                "coins": 200
              },
              "sellPrice": {},
              "image": null,
              "resourceGroup": null,
              "resourceTag": null,
              "meta": {},
              "pState": "PUBLISHED",
              "publishedAt": 1566850042148,
              "stackable": false,
              "consumable": false,
              "uses": null,
              "coolDownSecs": 0,
              "recoverySecs": 0,
              "activatable": true,
              "statusName": "boosted",
              "activeSecs": 900000,
              "tradable": false,
              "blockchain": false,
              "blockchainDefId": null
          ]
        },
        "currencySpent": {
          "coins": 200
        },
        "currencyBalances": {
          "createdAt": 1566850026783,
          "currencyMap": {
            "coins": {
              "consumed": 200,
              "balance": 2999800,
              "purchased": 0,
              "awarded": 3000000
            }
          },
          "playerId": "55ffc16e-f92b-44f3-98b0-68a7a4f24106",
          "updatedAt": 1566850132552
        }
      },
      "status": 200
    }
    

    Mapping this response to a C# object is trivial.

    1 Reply Last reply
    0
    • Michael CostaM Offline
      Michael CostaM Offline
      Michael Costa
      wrote on last edited by
      #2

      Hello! Thanks for your inquiry.

      The format of this response has been used for several years so to change it at this point would cause many errors for our clients. However, in situations like this, we have included the JsonFx library to help deserialize dynamic JSON objects with.

      One way to deserialize the JSON items would be to include a DeserializeItems(string) method in your Data class to be able to store them in an array using JsonFx's JsonReader.Deserialize(string) method:

      public List<Item> Items = new List<object>();
      public void DeserializeItems(string jsonResponse)
      {
          var response = JsonReader.Deserialize<Dictionary<string, object>>(jsonResponse);
          var data = response["data"] as Dictionary<string, object>;
          var items = data["items"] as Dictionary<string, object>;
      
          foreach (Dictionary<string, object> item in items.Values)
          {
              var newItem = new Item();
              newItem.itemId = (string)item["itemId"];
              newItem.defId = (string)item["boost_rapidfire"];
              newItem.quantity = (int)item["quantity"];
              // etc...
              Items.Add(newItem);
          }
      }
      

      Alternatively, you can also use JsonFx's JsonWriter.Serialize(object) method in the foreach loop to then be able to use Unity's JsonUtility to automatically map it as an Item.

      Understandably, both methods have their own pros and cons. However, it should be able to get the job done in this case.

      Hope this helps! Please let us know if you have further questions or inquiries about this.

      1 Reply Last reply
      0

      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

      With your input, this post could be even better 💗

      Register Login
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Solved
      • Unsolved
      • Users