45

I'm using C# in a console app and I need a quick way to check if a string being returned from another service is XML or JSON.

I know if it was just XML, I could check it against a schema, or if it was just JSON I could try to parse it with JSON.Net, but is there a quicker way - maybe using build in .Net functions - just to tell which it is before then going on to process it?

finoutlook
  • 2,523
  • 5
  • 29
  • 43

5 Answers5

66

Very simple:

  1. Valid JSON starts always with '{' or '['
  2. Valid XML starts always with '<'

I'm talking about non-space data.

Artyom
  • 31,019
  • 21
  • 127
  • 215
  • Sounds good to me, unless anyone can point out any exceptions? – finoutlook Aug 31 '11 at 11:20
  • 1
    @finoutlook - just take a look on specifications. For JSON it is explicitly stated that valid JSON starts with one of these two characters and for XML - you can read the formal grammar specifications. You'll see that it must start with `<`... – Artyom Aug 31 '11 at 11:26
  • Yeah I have to trust its a valid response from the server, so you're right it should meet the spec exactly. – finoutlook Aug 31 '11 at 11:54
  • 3
    If you are getting strings from a server and it might be JSON or it might be something else, this is not completely valid. What if it sends back another string wrapped in {} or <>? – Kyle Jurick Aug 05 '14 at 20:55
  • 3
    I don't understand why this is marked as the correct answer, all this does is confirm that the string COULD be JSON or XML. But is the string {{{{{ Valid JSON? No... – JLo Feb 23 '17 at 15:15
  • 4
    @JLo because the question didn't related to validation of XML or JSON but rather distinguishing between two in fastest way. – Artyom Feb 25 '17 at 20:54
  • 1
    I'm pretty sure the word "null" alone is valid JSON. That might be the only exception. – Menace May 10 '17 at 18:25
36
public static bool IsJson(this string input){
    input = input.Trim();
    return input.StartsWith("{") && input.EndsWith("}") 
           || input.StartsWith("[") && input.EndsWith("]");
}

it's a bit dirty but simple and quick

It is essentially enough to test the first character. Testing the last is a very rude way of testing well formedness. It doesn't guarantee it it simply heightens the chance that it is well formed.

If you wanted a more robust version you could take advantage of the short circuiting of if's to only evaluate well-formedness if the initial check is good. The below code relies on JSON.net

public static bool IsJson(this string input){
    input = input.Trim();
    Predicate IsWellFormed = () => {
             try {
                JToken.Parse(input);
             } catch {
                return false;
             }
             return true;
    }
    return (input.StartsWith("{") && input.EndsWith("}") 
            || input.StartsWith("[") && input.EndsWith("]"))
           && IsWellFormed()
}
Rune FS
  • 21,497
  • 7
  • 62
  • 96
  • 1
    I went with something similar, but only checking the beginning of the string - so just `TrimStart()` and `StartsWith()` – finoutlook Aug 31 '11 at 12:05
2

Thought I'd throw my solution in here too...

if (jsonData.Trim().Substring(0, 1).IndexOfAny(new[] {'[', '{'}) != 0)
     throw new Exception("The source file must be in JSON format");

or an extension...

public static bool IsJson(this string jsonData)
{
     return jsonData.Trim().Substring(0, 1).IndexOfAny(new[] { '[', '{' }) == 0;
}

usage:

if (!jsonData.IsJson())
     throw new Exception("The source file must be in JSON format");
Sam Jones
  • 4,443
  • 2
  • 40
  • 45
0

The answers are nice, but I think you all forget the end of the JSON. Here is a good example that your methods wouldn't catch, and it will throw an exception when the parser tries to parse the JSON.

{
    "positions": 
    [
        {
            "object": "position",
            "powerState": "1",
            "time": "72796",
            "place": "1",
            "clientId": ""
    ]
}

As you can see, it starts with { and ends with }, in the second hand starts with [ and ends with ], but someone forgot to close the 3rd {. This generates an error in the JSON parser.

I would say a more secure method is to check the beginning and the end for {[ that we find.

This doesn't happen often, but some people still handcraft their own JSON and forget some parts... Don't trust external data!

I hope it helps.

CarenRose
  • 1,266
  • 1
  • 12
  • 24
ManuVR
  • 46
  • 3
  • 6
    sure but the the OP is only asking about a quick way to decide if it is XML or JSON, not if it is a valid XML or JSON string – WiiMaxx Nov 27 '15 at 08:17
  • OP states that he wants a way to test it before processing it. You can't no if it's valid until you have processed it – Rune FS Jan 28 '17 at 11:05
0

Check the HttpContentHeaders.ContentType property in of the returned HttpResponseMessage - HttpContentHeaders.ContentType Property. You'll see something like application/json; charset=utf-8, text/json; charset=utf-8, text/xml; charset=utf-8. It returns a MediaTypeHeaderValue instance you can examine. In your case, you would look at the MediaTypeHeaderValue.SubType Property This is what I use to make sure I parse and validate accordingly.

This is the safest and most accurate way. Unless of course you have an API that is returning xml or json as a string.

If you just had the Content-Type value as a string, you could use MediaTypeHeaderValue.Parse(String) to help parse the Content-Type string.

The Content-Type property is defined as part the HTTP Spec and details are here: Content-Type [MDN]

Dave Black
  • 7,305
  • 2
  • 52
  • 41