【发布时间】:2021-09-03 06:31:11
【问题描述】:
我认为这很容易,但我在勾选我需要的所有框时遇到问题。
我需要
- 将对象序列化为 Json
- 忽略任何未设置的属性
- 使用 ENum 名称而不是整数值
我已经使用基于 .yaml 规范的开放 API 生成器为此生成了所有模型。
我的第一次尝试是从看起来像旧序列化器的代码中获取一些代码
let json<'t> (myObj:'t) =
use ms = new MemoryStream()
let serialiser: DataContractJsonSerializer = new DataContractJsonSerializer(typeof<'t>)
let settings: DataContractJsonSerializerSettings = new DataContractJsonSerializerSettings()
(new DataContractJsonSerializer(typeof<'t>)).WriteObject(ms, myObj)
Encoding.Default.GetString(ms.ToArray())
这个函数实际上做的一切都很好——除了它复制的是枚举数字而不是名称,我看不到一个选项来实现这一点。
我的另一个尝试是使用 System.Text.Json.JsonSerializer:
let options
= new JsonSerializerOptions(
)
options.DefaultIgnoreCondition <- JsonIgnoreCondition.WhenWritingDefault
options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
let jsonString:string = JsonSerializer.Serialize(shipmentRequest, options)
我尝试了一些不同的方法(包括排除 Enum 转换器),但总是出现以下错误。
Unable to cast object of type 'System.Int32' to type
'System.Nullable`1[Zimpla.Model.ExpressPackageReference+TypeCodeEnum]'
遇到问题的具体对象(大致)是:
[DataContract(Name = "ExpressPackageReference")]
public partial class ExpressPackageReference : IEquatable<ExpressPackageReference>, IValidatableObject
{
......etc
[DataMember(Name = "typeCode", EmitDefaultValue = false)]
public TypeCodeEnum? typeCode
{
get{ return _typeCode;}
set
{
_typeCode = value;
_flagtypeCode = true;
}
}
这个特定的属性甚至没有设置,所以理论上应该跳过它。我可能没有正确生成对象
【问题讨论】:
-
您能否提供一个对象的示例以及序列化后的样子?
-
@AndreasÅgren 谢谢 - 我刚刚更新了文本
-
您是否考虑过简单地手动进行 [反] 序列化?除非您有一个大的和/或非常不稳定的 API,否则使用现成的序列化程序节省的时间可能少于浪费在学习和配置它的时间。
-
@Guran - 这些代码都是使用 Open API 生成器生成的(它实际上是在使用 DHL API - 他们提供了一个 .yaml 文件用于定义)。所以我不确定我是否理解“现成的序列化程序”的意思。我认为顶部使用 System.Text.Json.JsonSerializer 的代码行已经准备好了。
-
@MartinThompson 抱歉,您的问题有点挑战框架。如果生成的代码给您带来麻烦,那么解决方案可能不是生成代码而是手动编写。 (并不是说代码生成可能不是正确的选择,只是应该是有意识的选择)
标签: f# system.text.json