[英]Write List<double> to Json array without indentation using System.Text.Json
NB: I am using System.Text.Json
not JSON.NET
for which there is similar question that has been answered.注意:我使用的是
System.Text.Json
而不是JSON.NET
,对此有类似的问题已得到解答。 I need the same answer but for System.Text.Json
.除了
System.Text.Json
之外,我需要相同的答案。 I would like to write my class to Json and ensure that it is human readable.我想将我的 class 写到 Json 并确保它是人类可读的。 To do this I have set the indent to true in options.
为此,我在选项中将缩进设置为 true。 However, the class contains a
List<double>
property which I don't want to indent as it makes the file very long.但是,class 包含一个
List<double>
属性,我不想缩进,因为它会使文件很长。
So I have this:所以我有这个:
public class ThingToSerialize
{
public string Name {get;set;}
//other properties here
public List<double> LargeList {get;set;}
};
var thing = new ThingToSerialize {Name = "Example", LargeList = new List<double>{0,0,0}};
var options = new JsonSerializerOptions
{
WriteIndented = true
};
options.Converters.Add(new DontIndentArraysConverter());
var s = JsonSerializer.Serialize(thing, options);
and I want it to serialize like this:我希望它像这样序列化:
{
"Name": "Example",
"LargeList ": [0,0,0]
}
Not this (or something along these lines):不是这个(或类似的东西):
{
"Name": "Example",
"LargeList ": [
0,
0,
0
]
}
I have written a JsonConverter
to achieve this:我写了一个
JsonConverter
来实现这个:
public class DontIndentArraysConverter : JsonConverter<List<double>>
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(List<double>);
}
public override List<double> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<List<double>>(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, List<double> value, JsonSerializerOptions options)
{
var s = JsonSerializer.Serialize(value);
writer.WriteStringValue(s);
}
}
However this writes the array as a string which I don't really want.但是,这会将数组写入我并不真正想要的字符串。 Whats the best approach for this?
最好的方法是什么?
ie you get "[1,2,3]" instead of [1,2,3]即你得到“[1,2,3]”而不是[1,2,3]
Secondly, the writer
object that is passed into the Write
function has an Options
property but this cannot be changed.其次,传递给
Write
function 的writer
object 具有Options
属性,但无法更改。 So if I write the array out manually using the writer object, it is indented.因此,如果我使用编写器 object 手动写出数组,它会缩进。
Thanks for your idea, I wrote my own serializer based on the Converters hint感谢您的想法,我根据转换器提示编写了自己的序列化程序
The idea is write a temp value during conversion, put correct array to a temp dict and replace them later这个想法是在转换期间写入一个临时值,将正确的数组放入临时字典并稍后替换它们
It's a bit late for you but maybe it can help other guys对你来说有点晚了,但也许它可以帮助其他人
public class CustomSerializer : IDisposable
{
private readonly Dictionary<string, string> _replacement = new Dictionary<string, string>();
public string Serialize<T>(T obj)
{
var converterForListInt = new DontIndentArraysConverterForListInt(_replacement);
var options = new JsonSerializerOptions
{
IgnoreNullValues = true,
WriteIndented = true
};
options.Converters.Add(converterForListInt);
var json = JsonSerializer.Serialize(obj, options);
foreach (var (k, v) in _replacement)
json = json.Replace(k, v);
return json;
}
public void Dispose()
{
_replacement.Clear();
}
public class DontIndentArraysConverterForListInt : JsonConverter<List<int>>
{
private readonly Dictionary<string, string> _replacement;
public DontIndentArraysConverterForListInt(Dictionary<string, string> replacement)
{
_replacement = replacement;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(List<int>);
}
public override List<int> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<List<int>>(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, List<int> value, JsonSerializerOptions options)
{
if (value.Count > 0)
{
var key = $"TEMPLATE_{Guid.NewGuid().ToString()}";
var sb = new StringBuilder();
sb.Append('[');
foreach (var i in value)
{
sb.Append(i);
sb.Append(',');
}
sb.Remove(sb.Length - 1, 1); // trim last ,
sb.Append(']');
_replacement.Add($"\"{key}\"", sb.ToString());
//
writer.WriteStringValue(key);
}
else
{
// normal
writer.WriteStartArray();
foreach (var i in value)
writer.WriteNumberValue(i);
writer.WriteEndArray();
}
}
}
}
Encountered this old question while trying to do the same thing for a List<string>
.在尝试对
List<string>
做同样的事情时遇到了这个老问题。 With .NET 6 (or at least package System.Text.Json v6.0.0.0) and later, this is now possible directly with System.Text.Json
and the Utf8JsonWriter
method WriteRawValue
.使用 .NET 6(或至少 package System.Text.Json v6.0.0.0)及更高版本,现在可以直接使用
System.Text.Json
和Utf8JsonWriter
方法WriteRawValue
。
class ListDoubleSingleLineConverter : JsonConverter<List<double>>
{
//Read override omitted
public override void Write(Utf8JsonWriter writer, List<double> value, JsonSerializerOptions options)
{
writer.WriteRawValue(
String.Concat(
"[ ",
// Depending on your values, you might want to use LINQ .Select() and String.Format() to control the output
String.Join(", ", value),
" ]"));
}
}
Of note from the documentation:文档中的注意事项:
When using this method, the input content will be written to the writer destination as-is, unless validation fails (when it is enabled).
使用此方法时,输入内容将按原样写入写入器目标,除非验证失败(启用时)。
(For my List<string>
case, this meant transforming value
with value.Select(v => String.Concat("\"", v, "\""))
before String.Join
, as otherwise the strings were emitted unquoted; when using WriteRawValue
you assume responsibility for the supplied argument being a well-formed JSON fragment.) (对于我的
List<string>
情况,这意味着在 String.Join 之前String.Join
value.Select(v => String.Concat("\"", v, "\""))
转换value
,否则字符串将不加引号; 使用WriteRawValue
时,您承担提供的参数是格式正确的 JSON 片段的责任。)
Tested with:测试:
JsonSerializerOptions options = new JsonSerializerOptions()
{
WriteIndented = true,
Converters = { new ListDoubleSingleLineConverter() },
};
var test = new
{
Name = "Example",
LargeList = new List<double>() { 1.0, 1.1, 1.2, 1.3 },
OtherProperty = 27.0,
};
Console.WriteLine(JsonSerializer.Serialize(test, options));
Output: Output:
{
"Name": "Example",
"LargeList": [ 1, 1.1, 1.2, 1.3 ],
"OtherProperty": 27
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.