JSON.Net - Serialize Property Name Without Quotes

How can I convert my Dataset to Json without Quotes and Dataset name?

You should probably avoid it as it is not compliant with the JSON standard.

That said, if you need to go ahead with it there's a great solution here by Christophe Geers: https://stackoverflow.com/a/7555096/4636912

Using the Json.NET library you can achieve this as follows:

[JsonObject(MemberSerialization.OptIn)] public class ModalOptions {
[JsonProperty]
public object href { get; set; }

[JsonProperty]
public object type { get; set; } }

When serializing the object use the JsonSerializer type instead of the static JsonConvert type.

For example:

var options = new ModalOptions { href = "file.html", type = "full" };
var serializer = new JsonSerializer(); var stringWriter = new
StringWriter(); using (var writer = new JsonTextWriter(stringWriter))
{
writer.QuoteName = false;
serializer.Serialize(writer, options);
}
var json = stringWriter.ToString();

This will produce:

{href:"file.html",type:"full"}

If you set the QuoteName property of the JsonTextWriter instance to false the object names will no longer be quoted.

How to enforce quotes on property names on JSON .NET

Json.NET does not currently implement strict parsing of JSON property names.

Internally JToken.Parse() constructs a JsonTextReader to parse a JSON string, and it appears the ability of JsonTextReaderto parse unquoted property names cannot currently be disabled.

When iterating through a JSON file via JsonTextReader.Read(), the method JsonTextReader.ParseProperty() is used to parse property names:

Newtonsoft.Json.JsonTextReader.ParseUnquotedProperty() 
Newtonsoft.Json.JsonTextReader.ParseProperty()
Newtonsoft.Json.JsonTextReader.ParseObject()
Newtonsoft.Json.JsonTextReader.Read()
Newtonsoft.Json.Linq.JContainer.ReadTokenFrom()

And, as seen from the current reference source, this method automatically handles properties that are double-quoted, single-quoted and unquoted:

private bool ParseProperty()
{
char firstChar = _chars[_charPos];
char quoteChar;

if (firstChar == '"' || firstChar == '\'')
{
_charPos++;
quoteChar = firstChar;
ShiftBufferIfNeeded();
ReadStringIntoBuffer(quoteChar);
}
else if (ValidIdentifierChar(firstChar))
{
quoteChar = '\0';
ShiftBufferIfNeeded();
ParseUnquotedProperty();
}
else
{
throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}

// REMAINDER OMITTED

As you can see there is no option to configure the reader to throw an exception for non-double-quoted properties.

As a workaround, the current Json.NET license allows for copying and modification. Thus you should be able to create your own public class StricterJsonTextReader : JsonReader copied from JsonTextReader, and modify ParseProperty() as follows:

private bool ParseProperty()
{
char firstChar = _chars[_charPos];
char quoteChar;

if (firstChar == '"')
{
_charPos++;
quoteChar = firstChar;
ShiftBufferIfNeeded();
ReadStringIntoBuffer(quoteChar);
}
else
{
// JsonReaderException.Create() is an internal static method,
// so you will need to replace this with some extension method
throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}

However, this may not be an entirely easy job, as JsonTextReader makes extensive use of utilities from the Src/Newtonsoft.Json/Utilities directory. You should budget a couple of days for making a minimal copy of the necessary utilities.

Alternatively, you could fork your own version of Json.NET, build it yourself, and use it instead of the official version. Either way, be sure to fork the source from the version you want to use:

Select the correct version

As an alternative to creating your own parser, you could preprocess your JSON with JsonReaderWriterFactory.CreateJsonReader() to ensure strict compliance with the JSON standard:

public static class JsonExtensions
{
public static JToken StrictParse(string json)
{
try
{
// Throw an exception if the json string is not in strict compliance with the JSON standard
// by tokenizing it with the JSON reader used by DataContractJsonSerializer:
using (var stream = GenerateStreamFromString(json))
using (var reader = System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(stream, System.Xml.XmlDictionaryReaderQuotas.Max))
{
while (reader.Read())
{
}
}
}
catch (Exception ex)
{
// Wrap the XmlException in a JsonReaderException
throw new JsonReaderException("Invalid JSON", ex);
}
// Then actually parse with Json.NET
return JToken.Parse(json);
}

static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
}

(You will need to add a reference to the appropriate .Net assembly for your framework.)

The performance will be worse since you will effectively be parsing your JSON twice, but the implementation effort is trivial.

Oddly enough, I was unable to use JavaScriptSerializer to check for strict JSON compliance because it also accepts unquoted property names!

// The following does not throw an exception:
new System.Web.Script.Serialization.JavaScriptSerializer().DeserializeObject("{foo : 'bar'}")

Related links:

  • Disable Support for Reading (Invalid JSON) Single Quote Strings for which the answer is to create your own JsonReader.

  • Unquoted json property name which has no answer.

  • Issue #646: Support "strict mode" for RFC7159 parsing which was closed by JamesNK. The discussion thread enumerates various ways that JsonTextReader extends the JSON standard, as well as some reasons as to why Newtonsoft has not yet implemented a strict parser.

    Even though the issue was closed, you could certainly add a comment requesting a strict parsing option. Certainly it seems like something they ought to provide.

How can I remove quotes from serilaized string?

One way to do it is by introducing new JsonConverter (sample). To separate the functionality of "raw serialization", you could introduce new type that would just wrap a string value, eg.

public class RawJson
{
public string Value { get; private set; }

public RawJson(string value)
{
Value = value;
}
}

Then you just check for this type in converter's CanConvert() and in WriteJson() you can just write

writer.WriteRawValue(((RawJson)value).Value);

Use JSON.net to serialize yyyyMMdd formatted date without quotes

You'll have to create your own JsonConverter because the one that comes out-of-the-box writes values as string and strings are always serialized with quotes...

You can copy the code of IsoDateTimeConverter and change it to write the value as an int.

Remove double quotes from JSON.SerializeObject string property

You can use a JsonConverter attribute to control the serialization of the value.

Technically this will no longer be JSON, but it sounds like you have a specific use-case which requires this.

I'm using a 3rd party visualization tool that generates the graph so I can't intercept/pre-process the colour property.

Source: https://blog.bitscry.com/2017/10/23/serializing-json-values-without-quotes/

You can make the JsonConverter like this:

public class PlainJsonStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return reader.Value;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteRawValue((string)value);
}
}

And use it like this:

public class Config
{
public string ID { get; set; }

public string Name { get; set; }

[JsonConverter(typeof(PlainJsonStringConverter))]
public string Colour{ get; set; }
}

Here's a DotNetFiddle showing it working: https://dotnetfiddle.net/dhIjvT

And this is the output {"ID":"8","Name":"floating-point","Colour":getColour('floating-point')}

JSON.Net Seralize values don't have quotation marks

In JSON format, numbers and booleans do not have quotes around them, while strings do (see JSON.org).

If you want quotes around all your primitives, you have a few options:

  1. Change the properties of the object you are serializing to be of type string.
  2. Put your values into a Dictionary<string, string> (or a DTO) and serialize that instead.
  3. Make a custom JsonConverter to do the conversion. This option has the advantage that it can apply globally so that you don't have to change all your classes.

The first two options are pretty self-explanatory. If you opted to go with a converter, the code might look something like this:

class PrimitiveToStringConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.IsPrimitive;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString().ToLower());
}

public override bool CanRead
{
get { return false; }
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

To use it, simply pass an instance of the converter to the JsonConvert.SerializeObject method.

string json = JsonConvert.SerializeObject(foo, new PrimitiveToStringConverter());

Demo:

class Program
{
static void Main(string[] args)
{
Foo foo = new Foo
{
Int = 6,
Bool = true,
Float = 3.14159
};

string json = JsonConvert.SerializeObject(foo, new PrimitiveToStringConverter());
Console.WriteLine(json);
}
}

class Foo
{
public int Int { get; set; }
public bool Bool { get; set; }
public double Float { get; set; }
}

Output:

{"Int":"6","Bool":"true","Float":"3.14159"}


Related Topics



Leave a reply



Submit