c# - 使用自定义 Json 序列化器创建集合

标签 c# json serialization asp.net-web-api json.net

此代码是 ASP.Net Web API Controller 的一部分,我有一个特殊要求,需要在将最终 Json 发送到 UI 之前修改其中的某些值

我当前的代码如下:

// Web API controller

public partial class ViewRController
        {
       [HttpGet]
            public DataMapList FetchEmployeeDataList()
            {
                DataMapList returnDataMapList = new DataMapList();

                return (returnDataMapList);
            }
        }

// Type definition and details

    [JsonObject]
        [JsonConverter(typeof(DataMapListSerializer))]
        public class DataMapList
        {
            public List<Dictionary<object, object>> employeeSalaryMappingList = null;

            public DataMapList()
            {
                employeeSalaryMappingList = new List<Dictionary<object, object>>();
                employeeSalaryMappingList.Add(new Dictionary<object, object>());

                employeeSalaryMappingList[0].Add(1, 10000);
                employeeSalaryMappingList[0].Add(2, 13000);
                employeeSalaryMappingList[0].Add(3, 15000);

                employeeSalaryMappingList.Add(new Dictionary<object, object>());

                employeeSalaryMappingList[1].Add(4, 9000);
                employeeSalaryMappingList[1].Add(5, 12000);
                employeeSalaryMappingList[1].Add(6, 11000);
            }
        }

// Custom Json serializer

public class DataMapListSerializer : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var employeeSalaryDataMapList = value as DataMapList;
            var employeeSalaryMappingList = employeeSalaryDataMapList.employeeSalaryMappingList;


            writer.WriteStartObject();
            foreach (var employeeSalaryMappingDictionary in employeeSalaryMappingList)
            {
                writer.WritePropertyName("ED");
                writer.WriteStartObject();

                foreach (var keyValuePair in employeeSalaryMappingDictionary)
                {
                    writer.WritePropertyName("ID-" + keyValuePair.Key);
                    serializer.Serialize(writer, keyValuePair.Value);
                }

                writer.WriteEndObject();
            }

            writer.WriteEndObject();
        }       

        public override bool CanConvert(Type objectType)
        {
            return typeof(DataMapList).IsAssignableFrom(objectType);
        }
    }

我面临的问题如下是我的结果:

{ 
   "ED": { "ID-1": 10000, "ID-2": 13000, "ID-3": 15000 }, 
  "ED": { "ID-4": 9000, "ID-5": 12000, "ID-6": 11000 } 
}

但是我期望以下结果,因为我正在序列化集合(.Net 列表类型,.Net 集合)

[ 
   "ED": { "ID-1": 10000, "ID-2": 13000, "ID-3": 15000 }, 
  "ED": { "ID-4": 9000, "ID-5": 12000, "ID-6": 11000 } 
]

事实上,当我尝试在 Json Lint 中验证时,当前结果,它显示有效的 Json 但终止了其中的一部分,因此它显示以下内容为有效的 Json,但这只是一个转移

{
    "ED": {
        "ID-4": 9000,
        "ID-5": 12000,
        "ID-6": 11000
    }
}

我尝试替换 writer.WriteStartObject();writer.WriteEndObject();通过 writer.WriteStartArray();writer.WriteEndArray(); ,在遍历类型中的 List 的第一个 foreach 循环之前,但这会导致异常,所以没有帮助

"exceptionMessage": "Token StartArray in state ObjectStart would result in an invalid JSON object. Path '

任何解决问题的建议,如果您需要任何说明,请告诉我

最佳答案

JSON ,名称-值对必须位于对象 {} 内;它们不能直接位于数组 [] 内。因此,您尝试创建的 JSON 无效,这就是您收到异常的原因:

[ 
   "ED": { "ID-1": 10000, "ID-2": 13000, "ID-3": 15000 }, 
   "ED": { "ID-4": 9000, "ID-5": 12000, "ID-6": 11000 } 
]

为了使其成为有效的集合,每个 ED 名称-值对必须包装在如下对象中:

[ 
   { 
      "ED": { "ID-1": 10000, "ID-2": 13000, "ID-3": 15000 } 
   }, 
   { 
      "ED": { "ID-4": 9000, "ID-5": 12000, "ID-6": 11000 } 
   }
]

一旦您看到这一点,解决方案就变得清晰了:在您的 DataMapListSerializer 中,您需要使用 writer.WriteStartArray()writer.WriteEndArray() code> 在循环之外,并且您需要在循环内添加 writer.WriteStartObject()writer.WriteEndObject()

    writer.WriteStartArray();

    foreach (var employeeSalaryMappingDictionary in employeeSalaryMappingList)
    {
        writer.WriteStartObject();

            writer.WritePropertyName("ED");
            writer.WriteStartObject();

            foreach (var keyValuePair in employeeSalaryMappingDictionary)
            {
                writer.WritePropertyName("ID-" + keyValuePair.Key);
                serializer.Serialize(writer, keyValuePair.Value);
            }

            writer.WriteEndObject();

        writer.WriteEndObject();
    }

    writer.WriteEndArray();

fiddle :https://dotnetfiddle.net/OT4HKM

关于c# - 使用自定义 Json 序列化器创建集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26840436/

相关文章:

android - 如何使用 Retrofit/Gson 反序列化 JSON 中相同类型但字段名称不同的对象列表?

c# - 有没有办法在不改变屏幕位置的情况下发帖(带表格的普通帖子)?

c# - MySQL 命令 - 日期错误

java - 使用 selenium Webdriver 在 Java 中读取 JSON 文件并写入 JSON 文件

android - com.google.gson.stream.MalformedJsonException : Expected ':' at line 1 column 55 path

Java 套接字 : Request-response pattern with object streams

wcf - 如何防止 WCF 将字节数组自动序列化为 base-64 编码字符串?

c# - .Net 与网站管理员工具(Google.Apis.Webmasters.v3 Nuget 包)斗争

c# - 将 Java TCP 套接字聊天程序转换为 .net C# TCP 聊天程序

java - 使用 gson.toJson 序列化嵌套的 org.json.JSONObject 添加到 "map"键