You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 21:12:21