Serialize as NDJSON using Json.NET

Is it possible to serialize to NDJSON (using JSON with line separators) using Json.NET? The Elasticsearch API uses NDJSON for bulk operations, and I cannot find anything, assuming that this format is supported by any .NET libraries.

This answer contains recommendations for deserializing NDJSON, and it has been noted that you can serialize each line independently and join a new line, but I will not necessarily call it supported.

+6
source share
2 answers

Since there is currently no built-in method in Json.NET for serializing the collection in NDJSON, the simplest answer would be to write to one TextWriter using a separate JsonTextWriter for each line with CloseOutput = false for each:

 public static partial class JsonExtensions { public static void ToNewlineDelimitedJson<T>(Stream stream, IEnumerable<T> items) { // Let caller dispose the underlying stream using (var textWriter = new StreamWriter(stream, new UTF8Encoding(false, true), 1024, true)) { ToNewlineDelimitedJson(textWriter, items); } } public static void ToNewlineDelimitedJson<T>(TextWriter textWriter, IEnumerable<T> items) { var serializer = JsonSerializer.CreateDefault(); foreach (var item in items) { // Formatting.None is the default; I set it here for clarity. using (var writer = new JsonTextWriter(textWriter) { Formatting = Formatting.None, CloseOutput = false }) { serializer.Serialize(writer, item); } // https://web.archive.org/web/20180513150745/http://specs.okfnlabs.org/ndjson/ // Each JSON text MUST conform to the [RFC7159] standard and MUST be written to the stream followed by the newline character \n (0x0A). // The newline charater MAY be preceeded by a carriage return \r (0x0D). The JSON texts MUST NOT contain newlines or carriage returns. textWriter.Write("\n"); } } } 

Sample violin .

Since individual NDJSON lines are likely to be short, but the number of lines may be large, this answer offers a streaming solution to avoid the need to allocate one line larger than 85 KB. As explained in Newtonsoft's Json.NET Performance Improvement Council , such large strings fall into a bunch of large objects and can subsequently degrade application performance.

+6
source

You can try the following:

 string ndJson = JsonConvert.SerializeObject(value, Formatting.Indented); 

but now I see that you do not just want the serialized object to be pretty printed. If the object you are serializing is some kind of collection or enumeration, could you do it yourself by serializing each element?

 StringBuilder sb = new StringBuilder(); foreach (var element in collection) { sb.AppendLine(JsonConvert.SerializeObject(element, Formatting.None)); } // use the NDJSON output Console.WriteLine(sb.ToString()); 
+1
source

Source: https://habr.com/ru/post/1269265/


All Articles