9

I currently have a REST app which returns a JSON string something like:

[{error: "Account with that email exists"}]

For when an error is thrown. I don't want to deserialize it into a custom "error" object, because it seems a bit wasteful and pointless. Is there a simple way to just extract a specific field out of a JSON string without making a custom class to reflect it.

Thanks

slaw
  • 611
  • 2
  • 7
  • 20
  • I would definitely deserialize. Any other string search operation would cost you more. – or hor May 18 '16 at 05:38
  • 1
    It would be good if you posted valid json. What you've given us is a segment of valid json, it's incomplete – Mick May 18 '16 at 06:01
  • Possible duplicate of [Deserialize json object into dynamic object using Json.net](http://stackoverflow.com/questions/4535840/deserialize-json-object-into-dynamic-object-using-json-net) – Mick May 18 '16 at 06:01

3 Answers3

17

You have a couple of options if you don't want to create a custom class, you can deserialize to dynamic:

dynamic tmp = JsonConvert.DeserializeObject(yourString);
string error = (string)tmp.error;

Or deserialize to a dictionary:

var dic = JsonConvert.DeserializeObject<Dictionary<string, string>>();
string error = dic["error"];
YetAnotherCoder
  • 366
  • 1
  • 9
  • 1
    this is definitely dynamic abuse – or hor May 18 '16 at 05:39
  • @orhor although I don't really agree that deserializing to dynamic when dealing with JSON is "definitely" dynamic abuse, I've posted an alternative. – YetAnotherCoder May 18 '16 at 05:45
  • 3
    Why you think it is dynamic abuse? It is avoiding one class to get created just to read error message. – Deepak Bhatia May 18 '16 at 05:48
  • we are in C#, which is a type language and it is its advantage. Why are you against the classes. The best way would be to have, let's say Message type with its Error property and deserialize right into it. I understand that some services might return unsystematic mixed or messed results, but it is different case. In my opinion the proper approach is to keep strongly typed. Sorry for beeing "old-school" – or hor May 18 '16 at 10:49
  • @orhor Thanks, I have decided to go with making an error class. Should I attempt to deserialize first into an error message, and if that fails, then I know it has received a legitimate response? Or how can I know which class to deserialize it into before actually seeing what's in it? – slaw May 18 '16 at 22:28
  • 1
    @orhor Ok I've decided to go with creating a subclass which just holds a success or fail message, if it's success then I deserialize the string again but this time into the actual class. – slaw May 18 '16 at 22:35
  • @orhor which one would be faster. Deserializing the JSON string into c# model just to get the value of one parameter or deserializing the string into a dynamic object and then fetching the required value using key? – Sunny Jan 24 '20 at 12:16
  • @Sunny if you mean performance-faster I believe faster would be the strong-typed way, although I have no exact measurement. I would not prefer dynamic objects. – or hor Feb 12 '20 at 07:59
8

No need third party libraries. Use native JavaScriptSerializer.

string input = "[{error: \"Account with that email exists\"}]";
var jss = new JavaScriptSerializer();

var array = jss.Deserialize<object[]>(input);
var dict = array[0] as Dictionary<string, object>;
Console.WriteLine(dict["error"]);

// More short with dynamic
dynamic d = jss.DeserializeObject(input);
Console.WriteLine(d[0]["error"]);
Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49
  • Great! I was hoping there would be a native solution – slaw May 18 '16 at 08:06
  • 1
    @S.Lukas Json.NET practically is native. There are so many microsoft libraries on github that are dependent on it. – Mick May 18 '16 at 23:17
2

Have a look at JObject.

dynamic obj = JObject.Parse("{ myerrors: [{error: \"Account with that email exists\"}] }");
var a = obj.myerrors[0];
string error = a.error;
Mick
  • 6,527
  • 4
  • 52
  • 67