0

I have this code that deserializes a JSON string.
Now we can see that the JSON string has for example this property: (Please notice that the CORS property exist under the "has" property so we need to check if "has" also exist before I beleive)

CORS

My question is. Sometimes it do happens that this property could be missing in the JSON string. As seen I use the below code where I use the try/catch block. Because if the CORS property is missing, I get an exception but exceptions are very performance expensive and now I use the try/catch block on 30 properties.

I then wonder how can we check with code if the CORS property exists first? Below line of code WITHOUT try/catch gives this error when CORS does not exist:

Cannot perform runtime binding on a null reference

String corsvalue = "";
try { corsvalue = deserializedTicker.has.CORS.ToLower(); } catch { }

JSON string:

{ 
  "id": "hello", 
  "name": "Hello",
  "has": { 
    "CORS": false,
    "CORS2": true
  },
  "has2": { 
    "CORS3": false,
    "CORS4": true
  }
}

Complete code:

String JSONstring = "{ \"id\": \"hello\", \"name\": \"Hello\", \"has\": { \"CORS\": false, \"CORS2\": true }, \"has2\": { \"CORS3\": false, \"CORS4\": true } }\";"

var deserializedTicker = JsonConvert.DeserializeObject<JsonInfo>(JSONstring);

String corsvalue = "";
try { corsvalue = deserializedTicker.has.CORS.ToLower(); } catch { }


public class JsonInfo 
{
  public string id { get; set; }
  public string name { get; set; }
  public JsonHasInfo has { get; set; }
  public JsonHas2Info has2 { get; set; }
}

public class JsonHasInfo
{
  public bool CORS { get; set; }
  public bool CORS2 { get; set; }
}

public class JsonHas2Info
{
  public bool CORS3 { get; set; }
  public bool CORS4 { get; set; }
}
dbc
  • 104,963
  • 20
  • 228
  • 340
Andreas
  • 1,121
  • 4
  • 17
  • 34
  • 2
    I know it is bad style to answer a question with a question, but i will do it anyway. My apologies. What are you trying to achieve by attempting to invoke `ToLower()` on a `bool` value (CORS is a property of type `bool`)? What is the meaning of this? –  Mar 07 '19 at 18:51
  • Yes I know I put it to a string, not the best but working. I do use a Dictionary of the string type and just thought to put all values as string as I have double,int and String in my original code. – Andreas Mar 07 '19 at 18:56
  • Did you carefully read [What is NRE](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) post already? (I think it is really duplicate, but maybe you are asking for something different than "better way for check if property is null than using NRE for flow control") – Alexei Levenkov Mar 07 '19 at 18:56
  • @alexei I have not red that, I could see that the link was very large and red a few pages but are not sure how to relate that to this exactly. I wonder if this is a valid way to do it or wrong? deserializedTicker.has != null and then check for: deserializedTicker.has.CORS != null – Andreas Mar 07 '19 at 19:02
  • By the way, a property (sometimes) missing in serialized Json data is just the property having the default value and the Json serializer just omitted writing/serializing the property with the default value. I don't know what your motivation/needs are that seemingly requires from you to test whether a property is explicitly present in the json data; but it kinda strikes me as an odd requirement to have... –  Mar 07 '19 at 19:06
  • Actually the property is sometimes missing completely from the string and not set as default as I use a unified library to get info from different sources and sometime one source do actually missing that property. So I need somehow to check so the property exist before using it. – Andreas Mar 07 '19 at 19:09
  • What i tried to communicate in my last comment was that if a property in serialized Json is missing, this missing property is assumed to have the default value when deserializing the json data back to the object. Since the default value is a known fixed/constant value, a json serializer might chose (or might be configured) to not write out properties that have such a known default value... –  Mar 07 '19 at 19:10
  • @elgonzo I tried to run the code again and I then know the CORS property is missing from the JSON string and then I get this error so I am not sure it is putting it to any type of default? ""Non-invocable member. CORS cannot be used like a method"" – Andreas Mar 07 '19 at 19:16
  • Please make an effort in reading and trying to understand the error message. The error has nothing to do with json or json deserialization (a possible bug in the json serialization/deserialization library you are using not withstanding), but indicates an error in how your code (or some other code you are using) is trying to incorrectly use/access the JsonHasInfo.CORS property of your C# class `JsonHasInfo`. That error points at a coding mistake, not related to json at all... –  Mar 07 '19 at 19:19
  • Yes this is what I think I do understand that it tries to use/access a property in the JSON string that actually doesn't exist. It seems that it assumes that the property exist and then can't access it and returns the error. The only way I can relate to it to check if the property exist Before trying to access it as we do with other scenarios in C# like checking for something != null before using it? – Andreas Mar 07 '19 at 19:22
  • No. That is not at all what the error is about. The error is not related to json. The error is related to a coding mistake somewhere in your project. Again, read the error message. Don't gloss over it. It says `"Non-invocable member. CORS cannot be used like a method"`. Clearly some code of yours tries to access (invoke) the property as if it were a method. But it is not a method, because it is a property. Read the error message, it is rather plain and is completely unrelated to the json data. Get json out of your head, this error is unrelated to the json data... –  Mar 07 '19 at 19:28
  • Yes you are right, I am sorry, I did the mistake to: deserializedTicker.has.CORS() where I only removed ToLower where the parantheses by mistake was left and became a "method". I do try to use this code and it seems to work: if(deserializedTicker.has.CORS != null){ /*do something*/ } – Andreas Mar 07 '19 at 19:32

1 Answers1

2

Here you go:

String JSONstring = "{ \"id\": \"hello\", \"name\": \"Hello\", \"has\": { \"CORS\": false, \"CORS2\": true }, \"has2\": { \"CORS3\": false, \"CORS4\": true }}";

            JObject jobject = JObject.Parse(JSONstring);

            JToken cors = jobject.SelectToken("has.CORS");
            if (cors != null)
            {
                JsonInfo myEvent = jobject.ToObject<JsonInfo>();
            }
Aldert
  • 4,209
  • 1
  • 9
  • 23