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

C# .Net5中如何让Newtonsoft对同一模型按不同格式序列化?

问题优化方案

以下方案均基于C# .NET 5环境实现,你可以根据自己的场景选择:

方案1:自定义构造/转换方法(无需第三方依赖)

不需要额外引入库,直接在目标模型内实现转换逻辑,统一管理赋值规则,避免到处写重复的for循环。

注:以下代码假设你的TypeModel中存储值的属性名为Value,请自行替换为你实际的属性名。

CollectionOptionDownloadModel转换实现

public class CollectionOptionDownloadModel
{
    // 原有属性保持不变
    public string sport { get; set; }
    public string plan { get; set; }
    public int fromDay { get; set; }
    public int fromMonth { get; set; }
    public int fromYear { get; set; }
    public int toDay { get; set; }
    public int toMonth { get; set; }
    public int toYear { get; set; }
    public int? eventId { get; set; }
    public string eventName { get; set; }
    public List<string> marketTypesCollection { get; set; }
    public List<string> countriesCollection { get; set; }
    public List<string> fileTypeCollection { get; set; }

    // 新增构造方法,直接传入源模型完成赋值
    public CollectionOptionDownloadModel(CollectionOptionModel source)
    {
        // 基础属性直接拷贝
        sport = source.sport;
        plan = source.plan;
        fromDay = source.fromDay;
        fromMonth = source.fromMonth;
        fromYear = source.fromYear;
        toDay = source.toDay;
        toMonth = source.toMonth;
        toYear = source.toYear;
        eventId = source.eventId;
        eventName = source.eventName;
        // 集合用Linq直接转换,自动判空避免空引用异常
        marketTypesCollection = source.marketTypesCollection?.Select(t => t.Value).ToList();
        countriesCollection = source.countriesCollection?.Select(t => t.Value).ToList();
        fileTypeCollection = source.fileTypeCollection?.Select(t => t.Value).ToList();
    }
}

SingleOptionResultsModel转换实现

public class SingleOptionResultsModel
{
    // 原有属性保持不变
    public string sport { get; set; }
    public string plan { get; set; }
    public int fromDay { get; set; }
    public int fromMonth { get; set; }
    public int fromYear { get; set; }
    public int toDay { get; set; }
    public int toMonth { get; set; }
    public int toYear { get; set; }
    public int? eventId { get; set; }
    public string eventName { get; set; }
    public string marketTypesCollection { get; set; }
    public string countriesCollection { get; set; }
    public string fileTypeCollection { get; set; }
    public List<string> fileList { get; set; }

    // 新增构造方法,支持同时传入文件列表
    public SingleOptionResultsModel(CollectionOptionModel source, List<string> fileList = null)
    {
        sport = source.sport;
        plan = source.plan;
        fromDay = source.fromDay;
        fromMonth = source.fromMonth;
        fromYear = source.fromYear;
        toDay = source.toDay;
        toMonth = source.toMonth;
        toYear = source.toYear;
        eventId = source.eventId;
        eventName = source.eventName;
        // 集合直接拼接为逗号分隔字符串,自动处理空集合
        marketTypesCollection = string.Join(",", source.marketTypesCollection?.Select(t => t.Value) ?? Enumerable.Empty<string>());
        countriesCollection = string.Join(",", source.countriesCollection?.Select(t => t.Value) ?? Enumerable.Empty<string>());
        fileTypeCollection = string.Join(",", source.fileTypeCollection?.Select(t => t.Value) ?? Enumerable.Empty<string>());
        this.fileList = fileList;
    }
}

使用示例

// 你的原始模型对象
var sourceModel = new CollectionOptionModel();

// 一行完成API调用模型转换
var downloadModel = new CollectionOptionDownloadModel(sourceModel);

// 一行完成结果模型转换,可直接传入API返回的文件列表
var resultModel = new SingleOptionResultsModel(sourceModel, apiReturnFileList);

方案2:AutoMapper映射(适合大量同类转换场景)

如果你后续有非常多类似的模型转换需求,推荐使用AutoMapper库,一次配置全局可用,不需要重复写赋值代码。

  1. 先通过NuGet安装AutoMapper和AutoMapper.Extensions.Microsoft.DependencyInjection(依赖注入场景使用)
  2. 全局配置映射规则:
var mapperConfig = new MapperConfiguration(cfg =>
{
    // 配置CollectionOptionModel转CollectionOptionDownloadModel规则
    cfg.CreateMap<CollectionOptionModel, CollectionOptionDownloadModel>()
        .ForMember(dest => dest.marketTypesCollection, opt => opt.MapFrom(src => src.marketTypesCollection.Select(t => t.Value).ToList()))
        .ForMember(dest => dest.countriesCollection, opt => opt.MapFrom(src => src.countriesCollection.Select(t => t.Value).ToList()))
        .ForMember(dest => dest.fileTypeCollection, opt => opt.MapFrom(src => src.fileTypeCollection.Select(t => t.Value).ToList()));

    // 配置CollectionOptionModel转SingleOptionResultsModel规则
    cfg.CreateMap<CollectionOptionModel, SingleOptionResultsModel>()
        .ForMember(dest => dest.marketTypesCollection, opt => opt.MapFrom(src => string.Join(",", src.marketTypesCollection.Select(t => t.Value))))
        .ForMember(dest => dest.countriesCollection, opt => opt.MapFrom(src => string.Join(",", src.countriesCollection.Select(t => t.Value))))
        .ForMember(dest => dest.fileTypeCollection, opt => opt.MapFrom(src => string.Join(",", src.fileTypeCollection.Select(t => t.Value))));
});
var mapper = mapperConfig.CreateMapper();
  1. 转换调用:
var downloadModel = mapper.Map<CollectionOptionDownloadModel>(sourceModel);
var resultModel = mapper.Map<SingleOptionResultsModel>(sourceModel);
// 赋值文件列表
resultModel.fileList = apiReturnFileList;

可选:自定义Getter方案

如果你只需要序列化转换,不需要修改目标模型的属性值,可以用自定义Getter实现,但是这种方案不适合需要修改属性的场景:

public class CollectionOptionDownloadModel
{
    // 直接挂载源模型
    public CollectionOptionModel Source { get; set; }
    // 所有属性通过Getter读取源模型的值
    public string sport => Source?.sport;
    public List<string> marketTypesCollection => Source?.marketTypesCollection?.Select(t => t.Value).ToList();
    // 其他属性以此类推
}

内容的提问来源于stack exchange,提问作者davezeetone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 22:09:03