Question

I want to find a good solution to handle deserializing plain strings that starts with a number or contains only a number, and understand why it doesn't work as it is now.

I can't control the input strings so I can't rely on them being valid Json, and at the moment I'm just checking if it is Json and if it isn't I'll wrap it in "[{}]", but I wanted to see if there was a better way.

This is how I'm deserializing it:

JsonConvert.DeserializeObject<MyClass[]>(myString);

My class has two properties:

[JsonProperty(PropertyName = "key")]
public string Key { get; set; }

[JsonProperty(PropertyName = "value")]
public string Value { get; set; }

If the input string is just "a" or "a2" it throws a Newtonsoft.Json.JsonException ("Unexpected character encountered while parsing value: a. Path '', line 0, position 0.") which is expected, however "2" and "2a" throws other errors. I'd like the same behavior for "2" and "2a" as for "a" and "a2".

Exception when passing in "2":

Newtonsoft.Json.JsonSerializationException : Error converting value 2 to type 'MyClass[]'. Path '', line 1, position 1.
System.ArgumentException : Could not cast or convert from System.Int64 to MyClass[].

Exception when passing in "2a":

System.FormatException : Input string was not in a correct format.

Why doesn't it work when the string contains only numbers or starts with a number? Is there a smarter way to fix this than to wrap the input string with "[{}]"?

Was it helpful?

Solution

Your problem stems from the JSON parser and what you're passing it.

2 is a valid value, for example imagine JsonConvert.DeserializeObject<int>('2');

But a2 is not as it likely sees it as an incomplete identifier or property which can't exist outside of an object literal. It's not a string as there's no enclosing quotes.

You're basically trying to get the JSON parser to parse invalid JSON, which it won't do of course.

In your case I'd actually do something like this:

MyClass cls = null;

if (json.StartsWith("{")) {
    cls = JsonConvert.DeserializeObject<MyClass>(json);
} else {
    cls = new MyClass() {
        Key = json
    };
}

This checks for {} which objects should begin/end with. If we find a { we can assume it's an object and deserialize, if not we manually create an instance of your class and fill out the value.

I'm of course making some assumptions here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top