建站有哪些需求,google seo是什么啊,免费建站赚钱,农业交易平台网站建设默认情况下#xff0c;枚举是以其整数形式进行 JSON 序列化#xff0c;这通常会导致与消费者应用缺乏互操作性#xff0c;因为他们需要事先了解这些数字的实际含义。因此#xff0c;我们希望它们在一些情况下以字符串的形式进行序列化。本文将讲解实现这一目标的各种方法。… 默认情况下枚举是以其整数形式进行 JSON 序列化这通常会导致与消费者应用缺乏互操作性因为他们需要事先了解这些数字的实际含义。因此我们希望它们在一些情况下以字符串的形式进行序列化。本文将讲解实现这一目标的各种方法。1枚举序列化的默认行为为了演示我们来创建一个简单的 Modelpublic class Circle
{public double Radius { get; set; }public Color BgColor { get; set; }
}public enum Color
{White, LightGray, Black
}我们用 System.Text.Json 中的 Serialize 方法序列化一个 Circle 对象using System.Text.Json;var json JsonSerializer.Serialize(new Circle
{Radius 10.1,BgColor Color.Black
});Console.WriteLine(json);我们来看一下这个 Model 序列化为 Json 后的字符串{ Radius: 10.1, BgColor: 2 }正如你看到的枚举属性的值Color.Black被序列化为 JSON 字符串后表现为一个整数2。作为序列化结果 JSON 的消费者在没有文档的情况下无法知道这个整数代表的业务含义。所以问题来了。如何将枚举属性序列为更直观的字符串形式呢即如何将上面示例中的对象序列化为{ Radius: 10.1, BgColor: Black }要把枚举序列化为字符串Dotnet 标准库 System.Text.Json 和 Newtonsoft 库都为此提供了一个转换器分别为 JsonStringEnumConverter 和 StringEnumConverter。下面来看看它们的用法。2基于标注的方式Dotnet 标准库和 Newtonsoft 库都提供了一个转换器特性 JsonConverterAttribute我们可以用它来选择性地标注要序列化为字符串形式的枚举属性或类型。标注枚举属性我们可以在枚举属性上使用 JsonConverterAttribute 特性来标注 BgColor 属性并使用 JsonStringEnumConverter 转换器如下using System.Text.Json.Serialization;public class Circle
{public double Radius { get; set; }[JsonConverter(typeof(JsonStringEnumConverter))]public Color BgColor { get; set; }
}此时序列化的结果为{ Radius: 10.1, BgColor: Black }Newtonsoft 库也是类似的把 JsonStringEnumConverter 替换为 StringEnumConverter 即可本文就不重复举列了。标注枚举类型JsonConverterAttribute 特性也可以应用在自定义类型上面把它应用在 Color 枚举类型上using System.Text.Json.Serialization;[JsonConverter(typeof(JsonStringEnumConverter))]
public enum Color
{White, LightGray, Black
}这样所有的 Color 枚举都会序列化为字符串形式。3基于选项的方式在一些不方便修改 Model 或枚举类型定义的情况下如调用第三方 SDK就不能使用标注的方式将枚举序列化为字符串了。Dotnet 标准库和 Newtonsoft 库还提供了带有转换选项参数的序列化方法允许我们使用行内Inline方式实现这一目标。Dotnet 标准库示例如下public static string SerializeWithStringEnum(object obj)
{var options new JsonSerializerOptions();options.Converters.Add(new JsonStringEnumConverter());return JsonSerializer.Serialize(obj, options);
}而 Newtonsoft 库稍有不同public static string SerializeWithStringEnum(object obj)
{var converter new StringEnumConverter();return JsonConvert.SerializeObject(obj, converter);
}4全局注册的方式基于特性标注的方式让我们可以灵活地以可控的方式来操作枚举的序列化。而基于选项的方式允许我们在特定环境下按需处理对象的序列化。但是有没有办法让所有的枚举在默认情况下被序列化为字符串呢答案是有的。对控制台应用程序或 Dotnet 类库就简单了直接封装一个通用的序列化方法即可。这里我们主要关心如何在 ASP.NET Core 应用程序中注册全局的序列化规则。在 ASP.NET Core Web API 应用中需要在 DI 管道中注册枚举转换器如下var builder WebApplication.CreateBuilder(args);builder.Services.AddControllers().AddJsonOptions(options {options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());});var app builder.Build();app.MapControllers();app.Run();在 ASP.NET Core Minimal API 中也是需要在 DI 管道中注册枚举转换器但使用的是 Configure 方式var builder WebApplication.CreateBuilder(args);
builder.Services.ConfigureJsonOptions(options
{options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
});var app builder.Build();app.MapGet(/, () new Circle
{Radius 10.1,BgColor Color.Black
});app.Run();如上所述我们可以通过全局注册的方式来设置应用程序在默认情况下将枚举序列化为字符串这样可以保持 Model 的干净也不需要在序列化时指定明确的选项。5标志枚举的序列化标志枚举bit-mask 枚举的默认序列化输出也是一个整数而不是使用标志Flag的组合来表示。例如using System.Text.Json;var colors Color.LightGray | Color.Black;
var json JsonSerializer.Serialize(new { Colors colors });Console.WriteLine(json);[Flags]
public enum Color
{White 0, LightGray 1, Black 2
}序列化结果为{ Colors: 3 }我们希望输出的是枚举的组合结果却是一个数字这对消费者来说很难理解它真正的意义我们希望它序列化为文件的组合。使用前面的枚举字符串转换器可以解决这个问题以基于选项的方式为例示例代码如下using System.Text.Json;
using System.Text.Json.Serialization;var options new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter());var colors Color.LightGray | Color.Black;
var json JsonSerializer.Serialize(new { Colors colors }, options);Console.WriteLine(json);{ Colors: LightGray, Black }这样就得到我们想要的文本组合序列化结果了。6自定义枚举字符串在将枚举序列化为字符串时我们可能希望进行一些微调。例如转换为 camelCase 或其它更有意义的文本形式。序列化为 camelCase 形式JsonStringEnumConverter 有一个接收命名策略的重载构造函数给其传入 JsonNamingPolicy.CamelCase 参数即可将枚举序列为 camelCase 文本形式例如var options new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
var json JsonSerializer.Serialize(new Circle
{Radius 10.1,BgColor Color.LightGray
});Console.WriteLine(json);序列化结果为{ Radius: 10.1, BgColor: lightGray }序列化为自定义文本由于语言中的变量命名规则枚举成员在以常规方式序列化时并不总是能传达有意义的文本。为了解决这个问题我们可以使用 EnumMemberAttribute 特性它是专门为此目的引入的。我们来定义一个新的枚举public enum ColorScheme
{[EnumMember(Value 白/蓝)]WhiteBlue,[EnumMember(Value 红/黑)]RedBlack,
}我们定义了一个 ColorScheme 枚举在其成员上标注 EnumMember 特性以提供更有意义的文本表达。遗憾的Donet 标准库 System.Text.Json 原生暂不支持这种自定义文本的序列化。但 Newtonsoft 库是支持的示例代码如下using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Runtime.Serialization;var converter new StringEnumConverter();
var json JsonConvert.SerializeObject(new TShirt
{Name 男士衬衫-休闲款,ColorScheme ColorScheme.WhiteBlue
}, converter);Console.WriteLine(json);public class TShirt
{public string? Name { get; set; }public ColorScheme ColorScheme { get; set; }
}序列化后输出结果{ Name: 男士衬衫-休闲款, ColorScheme: 白/蓝 }序列化后我们可以看到它输出了我们想要的文本。注虽然 Donet 标准库原生暂不支持将枚举序列化为自定义的文本但依然可以通过自定义转换器来实现。7总结枚举默认是以其整数形式进行 JSON 序列化的这要求消费者事先了解这些数字的实际含义给代码的理解也带来了一定的困难。所以 Dotnet 基础库和流行的 Newtonsoft 库都提供了将枚举序列化为字符串的多种方法。根据需求可以选择使用本文讲的基于特性标注的方式、基于选项参数的方式和全局方式。另外除了可以将枚举序列化为成员名字符串还可以自定义文本的输出如输出为 camelCase 文本形式和自定义输出的文本内容等。