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

如何自定义JSON序列化,将MetadataContextViewModel的Name设为对象键?

可行实现方案

方案1:自定义JSON转换器(推荐)

无需修改原MetadataContextViewModel结构,通过自定义转换器直接控制序列化/反序列化逻辑,适配System.Text.Json或Newtonsoft.Json两种常用库:

针对System.Text.Json的实现

public class MetadataContextViewModelConverter : JsonConverter<MetadataContextViewModel>
{
    // 反序列化逻辑:将键值对结构转回原数组格式
    public override MetadataContextViewModel Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var dict = JsonSerializer.Deserialize<Dictionary<string, IdTypeModel>>(ref reader, options);
        return new MetadataContextViewModel
        {
            Items = dict.Select(kv => new MetadataItemViewModel
            {
                Name = kv.Key,
                Id = kv.Value.Id,
                Type = kv.Value.Type
            }).ToList()
        };
    }

    // 序列化逻辑:将数组转成键值对结构
    public override void Write(Utf8JsonWriter writer, MetadataContextViewModel value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        foreach (var item in value.Items)
        {
            writer.WriteStartObject(item.Name);
            writer.WriteNumber("id", item.Id);
            writer.WriteString("type", item.Type);
            writer.WriteEndObject();
        }
        writer.WriteEndObject();
    }
}

使用方式:给MetadataContextViewModel添加特性[JsonConverter(typeof(MetadataContextViewModelConverter))],或序列化时手动传入转换器。

针对Newtonsoft.Json的实现

public class MetadataContextViewModelConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(MetadataContextViewModel);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var dict = serializer.Deserialize<Dictionary<string, IdTypeModel>>(reader);
        return new MetadataContextViewModel
        {
            Items = dict.Select(kv => new MetadataItemViewModel
            {
                Name = kv.Key,
                Id = kv.Value.Id,
                Type = kv.Value.Type
            }).ToList()
        };
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var model = (MetadataContextViewModel)value;
        writer.WriteStartObject();
        foreach (var item in model.Items)
        {
            writer.WritePropertyName(item.Name);
            serializer.Serialize(writer, new { id = item.Id, type = item.Type });
        }
        writer.WriteEndObject();
    }
}

使用方式:同样给ViewModel添加[JsonConverter(typeof(MetadataContextViewModelConverter))]特性,或在序列化配置中注入转换器。

方案2:通过AutoMapper直接映射到目标结构

利用已有的AutoMapper,直接将原实体/ViewModel映射为字典或匿名类型,序列化后自然得到目标JSON:

// 配置映射规则:从Domain实体直接转成键值对字典
CreateMap<MetadataContext, Dictionary<string, IdTypeModel>>()
    .ConvertUsing(src => src.Items.ToDictionary(
        item => item.Name,
        item => new IdTypeModel { Id = item.Id, Type = item.Type }
    ));

// 或者映射到匿名类型(无需定义额外类)
CreateMap<MetadataContext, object>()
    .ConvertUsing(src => src.Items.ToDictionary(
        item => item.Name,
        item => new { id = item.Id, type = item.Type }
    ));

后续直接序列化这个映射后的字典/匿名对象即可,原ViewModel可保留用于其他业务场景。

方案3:序列化专用包装类

如果不想修改原ViewModel也不想写转换器,可以做一个轻量包装类,利用JsonExtensionData特性实现动态键值对:

public class MetadataContextSerializationWrapper
{
    private readonly MetadataContextViewModel _viewModel;

    public MetadataContextSerializationWrapper(MetadataContextViewModel viewModel)
    {
        _viewModel = viewModel;
    }

    [JsonExtensionData]
    public Dictionary<string, JsonElement> ExtensionData
    {
        get
        {
            var dict = new Dictionary<string, JsonElement>();
            foreach (var item in _viewModel.Items)
            {
                var json = JsonSerializer.SerializeToElement(new { id = item.Id, type = item.Type });
                dict.Add(item.Name, json);
            }
            return dict;
        }
    }
}

序列化时只需包装原ViewModel:

var wrapper = new MetadataContextSerializationWrapper(viewModel);
var targetJson = JsonSerializer.Serialize(wrapper);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:20:18