Skip to content

Instantly share code, notes, and snippets.

@randyburden
Created July 4, 2013 04:42
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save randyburden/5924981 to your computer and use it in GitHub Desktop.
Save randyburden/5924981 to your computer and use it in GitHub Desktop.
A Json.NET JsonConverter that can handle converting the following values into boolean values: true, false, yes, no, y, n, 1, 0.
using System;
using Newtonsoft.Json;
namespace JsonConverters
{
/// <summary>
/// Handles converting JSON string values into a C# boolean data type.
/// </summary>
public class BooleanJsonConverter : JsonConverter
{
#region Overrides of JsonConverter
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert( Type objectType )
{
// Handle only boolean types.
return objectType == typeof( bool );
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>
/// The object value.
/// </returns>
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
{
switch ( reader.Value.ToString().ToLower().Trim() )
{
case "true":
case "yes":
case "y":
case "1":
return true;
case "false":
case "no":
case "n":
case "0":
return false;
}
// If we reach here, we're pretty much going to throw an error so let's let Json.NET throw it's pretty-fied error message.
return new JsonSerializer().Deserialize( reader, objectType );
}
/// <summary>
/// Specifies that this converter will not participate in writing results.
/// </summary>
public override bool CanWrite { get { return false; } }
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param><param name="value">The value.</param><param name="serializer">The calling serializer.</param>
public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer )
{
}
#endregion Overrides of JsonConverter
}
}
@harishrathi
Copy link

thanks a lot for sharing

@frederikprijck
Copy link

Thanks for sharing !

@PaulChernoch-Shell
Copy link

I was just about to implement this when I spotted yours. Thanks!

@ykurniawan
Copy link

nice, thanks.

@rpj
Copy link

rpj commented Dec 20, 2018

Has anyone actually tested this implementation, including the author? I doubt it, because it does not work.

@rpj
Copy link

rpj commented Dec 20, 2018

If you try this:

namespace ConsoleApp1
{
    public class BooleanJsonConverter {...}

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"\"true\" -> {JsonConvert.DeserializeObject<bool>("true")}");
            try
            {
                Console.WriteLine($"\"yes\" -> {JsonConvert.DeserializeObject<bool>("yes", new BooleanJsonConverter())}");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Exception: {e}");
            }
      }
}

You will get this:

"true" -> True
Exception: Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: y. Path '', line 0, position 0.
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonConverter[] converters)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonConverter[] converters)
   at ConsoleApp1.Program.Main(String[] args) in C:\Users\ryanj\PersonalDev\ConsoleApp1\ConsoleApp1\Program.cs:line 247

which is exactly the same failure mode as described by this SO post, for which this very Gist was proposed as a solution.

@DreamRunnerMoshi
Copy link

DreamRunnerMoshi commented Mar 12, 2019

I tested and it works for me like this.

class Program
  {
      static void Main(string[] args)
      {
          Console.WriteLine($"\"true\" -> {JsonConvert.DeserializeObject<bool>("true")}");
          try
          {
              //Console.WriteLine($"\"yes\" -> {JsonConvert.DeserializeObject<bool>("yes", new BooleanConverter())}");
              Console.WriteLine($"\"yes\" -> {JsonConvert.DeserializeObject<MyClass>("{IsValid: 'no'}", new BooleanJsonConverter())}");
          }
          catch (Exception e)
          {
              Console.WriteLine($"Exception: {e}");
          }
      }

And My Class is :

public class MyClass
    {
        public bool IsValid { get; set; }

        public override string ToString()
        {
            return IsValid.ToString();
        }
    }

@thakurarun
Copy link

thakurarun commented May 26, 2021

It's really nice way to resolve booleans. Just addon for nullable booleans

 public override bool CanConvert(Type objectType)
        {
            if (Nullable.GetUnderlyingType(objectType) != null)
            {
                return Nullable.GetUnderlyingType(objectType) == typeof(bool);
            }
            return objectType == typeof(bool);
        }

@bert2
Copy link

bert2 commented Mar 15, 2022

If you try this:

namespace ConsoleApp1
{
    public class BooleanJsonConverter {...}

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"\"true\" -> {JsonConvert.DeserializeObject<bool>("true")}");
            try
            {
                Console.WriteLine($"\"yes\" -> {JsonConvert.DeserializeObject<bool>("yes", new BooleanJsonConverter())}");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Exception: {e}");
            }
      }
}

You will get this:

"true" -> True
Exception: Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: y. Path '', line 0, position 0.
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonConverter[] converters)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonConverter[] converters)
   at ConsoleApp1.Program.Main(String[] args) in C:\Users\ryanj\PersonalDev\ConsoleApp1\ConsoleApp1\Program.cs:line 247

which is exactly the same failure mode as described by this SO post, for which this very Gist was proposed as a solution.

You are trying t o deserialize the input yes into a bool. This is not a valid JSON string. Try it with "yes" instead:

bool yes = JsonConvert.DeserializeObject<bool>("\"yes\"", new BooleanJsonConverter())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment