如何将JSON数组映射为C# DTO数组?
JSON数组映射C# DTO数组异常解决
问题场景
需要将包含整数数组的JSON,映射到包含自定义DTO数组的C#类中,反序列化时抛出类型转换异常。
JSON输入
{ "make": "Opel", "model": "Omega", "partsId": [ 38, 102, 23, 116, 46, 68, 88, 104, 71, 32, 114 ] }
C# DTO定义
ImportCarDTO:
public class ImportCarDTO { [JsonProperty("make")] public string Make { get; set; } = null!; [JsonProperty("model")] public string Model { get; set; } = null!; [JsonProperty("partsId")] public ImportPartCarDTO[] PartsId { get; set; } = null!; }
ImportPartCarDTO:
public class ImportPartCarDTO { public int Id { get; set; } }
异常信息
ArgumentException: Could not cast or convert from System.Int64 to CarDealer.DTOs.Import.ImportPartCarDTO.
已通过Automapper忽略PartsId成员准备手动映射,但反序列化JSON时直接抛出上述异常。
解决方法
方法1:自定义JsonConverter
为ImportPartCarDTO创建自定义转换器,实现整数到DTO的自动转换:
public class ImportPartCarConverter : JsonConverter<ImportPartCarDTO> { public override ImportPartCarDTO ReadJson(JsonReader reader, Type objectType, ImportPartCarDTO existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Integer) { return new ImportPartCarDTO { Id = Convert.ToInt32(reader.Value) }; } throw new JsonSerializationException("Unexpected token type for ImportPartCarDTO"); } public override void WriteJson(JsonWriter writer, ImportPartCarDTO value, JsonSerializer serializer) { writer.WriteValue(value.Id); } }
使用方式二选一:
- 在DTO类上标记转换器:
[JsonConverter(typeof(ImportPartCarConverter))] public class ImportPartCarDTO { public int Id { get; set; } } - 反序列化时传入转换器配置:
var settings = new JsonSerializerSettings(); settings.Converters.Add(new ImportPartCarConverter()); var car = JsonConvert.DeserializeObject<ImportCarDTO>(jsonString, settings);
方法2:中间类中转转换
先定义与JSON结构完全匹配的中间类,再手动转换为目标DTO:
public class TempCarDTO { public string Make { get; set; } = null!; public string Model { get; set; } = null!; public int[] PartsId { get; set; } = null!; } // 反序列化后转换 var tempCar = JsonConvert.DeserializeObject<TempCarDTO>(jsonString); var importCar = new ImportCarDTO { Make = tempCar.Make, Model = tempCar.Model, PartsId = tempCar.PartsId.Select(id => new ImportPartCarDTO { Id = id }).ToArray() };
方法3:Automapper自定义映射规则
在Automapper配置中添加数组转换逻辑:
var config = new MapperConfiguration(cfg => { cfg.CreateMap<TempCarDTO, ImportCarDTO>() .ForMember(dest => dest.PartsId, opt => opt.MapFrom(src => src.PartsId.Select(id => new ImportPartCarDTO { Id = id }).ToArray())); });
内容的提问来源于stack exchange,提问作者Krasimir Dimitrov
相关产品推荐
相关产品推荐

