[英]How to convert json array to collection with System.Text.Json;
我有一個User
class 具有ISet<Role>
類型的屬性Roles
,其中Role
是enum
類型。 在 JSON 中,我得到了該屬性的數組(例如, "Roles":["Admin","User"]
)。 如何編寫自定義轉換器將此數組轉換為ISet
集合?
我試過寫這個 class:
class CustomStringToRoleConverter : JsonConverter<ISet<User.Role>> {
public override ISet<User.Role> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
return null;
}
public override void Write(Utf8JsonWriter writer, ISet<User.Role> roles, JsonSerializerOptions options) {
StringBuilder builder = new StringBuilder();
builder.Append(string.Join(",", roles.Select(role => role.ToString()).ToArray()));
writer.WriteStartArray();
writer.WriteStringValue(builder.ToString());
writer.WriteEndArray();
}
}
但我不知道在Read
方法中該怎么做。 如何從Utf8JsonReader
獲取數組? 有一個GetString
方法,但是當我調用它時它會引發異常:
InvalidOperationException:無法將令牌類型“StartArray”的值作為字符串獲取。
我正在使用System.Text
和System.Text.Json
。
JSON "Roles":["Admin","User"]
屬性是一個字符串值數組,而不是包含逗號分隔值的單個字符串值。 因此,編寫自定義轉換器的最簡單方法如下:
class CustomStringToRoleConverter : JsonConverter<ISet<User.Role>> {
public override ISet<User.Role> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
JsonSerializer.Deserialize<List<string>>(ref reader, options)
?.Select(s => Enum.Parse<User.Role>(s))
?.ToHashSet(); // Or use a SortedSet if you prefer
public override void Write(Utf8JsonWriter writer, ISet<User.Role> roles, JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, roles.Select(r => r.ToString()), options);
}
轉換器只是對字符串集合進行序列化和反序列化,然后將項目解析或格式化為Role
枚舉,作為后處理或預處理步驟。 (為了比較,您現有的Write()
方法將生成"Roles": ["Admin,User"]
與問題開頭段落中顯示的 JSON 不匹配。)
樣品小提琴#1在這里。
如果您非常關心性能並且更喜歡不反序列化為中間List<string>
的更“手動”方法,您可以這樣做:
class CustomStringToRoleConverter : JsonConverter<ISet<User.Role>> {
public override ISet<User.Role> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
return null; // Or throw an exception if you don't want to allow null
else if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException();
var set = new HashSet<User.Role>();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndArray)
return set;
else if (reader.TokenType == JsonTokenType.String)
set.Add(Enum.Parse<User.Role>(reader.GetString()));
else
{
//reader.Skip();
throw new JsonException(); // Unexpected token;
}
}
throw new JsonException(); // Truncated file;
}
public override void Write(Utf8JsonWriter writer, ISet<User.Role> roles, JsonSerializerOptions options)
{
writer.WriteStartArray();
foreach (var value in roles)
writer.WriteStringValue(value.ToString());
writer.WriteEndArray();
}
}
樣品小提琴#2在這里。
或者,您可以簡單地將JsonStringEnumConverter
添加到JsonSerializerOptions.Converters
以將所有枚舉序列化為字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.