升级.NET7后,JsonApiDotNetCore中DTO的Int属性需转为JSON字符串
升级JsonApiDotNetCore API至.NET 7时,实现int类型属性在JSON:API attributes中以字符串序列化/反序列化
我们正将基于JsonApiDotNetCore的C# API从.NET Core 3.1升级到.NET 7,同步升级Entity Framework到EF 7、JsonApiDotNetCore到5.1版本(均为当前最新版)。
因React前端的特殊需求,所有JSON对象中的int类型需以字符串形式处理,包含返回响应和提交请求数据。普通属性实现该需求无阻碍,但需要将属性映射到JSON:API的attributes区域时,直接给标记[Attr]的属性添加JsonConverter无法生效。
我们尝试过在DTO中复制属性的变通方案:定义字符串类型的PublicEmployeeId并标记[Attr],关联原int类型的EmployeeId属性,同时在EF配置中设置转换逻辑,但保存数据时出现错误——原EmployeeId作为外键,导致JsonApiController生成的SQL查询中列重复。该方案不仅繁琐,还引入了额外问题。
我们希望直接将原int类型属性映射到attributes区域并序列化为字符串,同时支持反序列化(字符串转int),但暂未找到可行方法。此前使用Newtonsoft.Json时,可通过自定义JsonConverter实现此功能,但现在必须使用System.Text.Json,无法沿用原有方案。
尝试过的代码示例
DTO代码
public class MyDTO { public int Id { get; set ;} [NotMapped] public int EmployeeId { get; set ;} [NotMapped] [Attr(PublicName = "employeeid")] public string PublicEmployeeId { get => EmployeeId.ToString(); set { if (int.TryParse(value, out int result)) EmployeeId = result; } } }
EF配置代码
builder.Property(x => x.PublicEmployeeId) .HasConversion( // Convert to DB type v => int.Parse(v), // Convert to model type v => v.ToString() ) .HasColumnName("employeeid");
原Newtonsoft.Json转换器代码
/// <summary> /// Custom JsonConverter, convert all Id properties in json to string when converting to json. /// </summary> public class FormatIntIdsAsStringConverter : JsonConverter { public override bool CanRead => false; public override bool CanWrite => true; public override bool CanConvert(Type type) => type == typeof(int); public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer) { var path = writer.Path; if (!string.IsNullOrEmpty(path)) { var propertyName = path.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Last(); if (propertyName.Contains("Id")) { int number = (int)value; writer.WriteValue(number.ToString(CultureInfo.InvariantCulture)); return; } } writer.WriteValue(value); } public override object ReadJson( JsonReader reader, Type type, object existingValue, JsonSerializer serializer) { throw new NotSupportedException(); } }
内容的提问来源于stack exchange,提问作者Michiel van Vaardegem
相关产品推荐
相关产品推荐

