【问题标题】:Creating a collection with custom Json serializer使用自定义 Json 序列化程序创建集合
【发布时间】:2015-01-06 13:23:51
【问题描述】:

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

我当前的代码如下所示:

// 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 List 类型,.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
    }
}

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

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

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

【问题讨论】:

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


    【解决方案1】:

    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(),你需要在你的循环中添加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();
    

    小提琴:https://dotnetfiddle.net/OT4HKM

    【讨论】:

    • { "data": [ { "ID44": 2, "ID43": "Block" }, { "ID44": 1, "ID43": "Train" } ] } 这将是一个有效的 Json,我已经验证过了。你是对的,我需要将所有内容包装在 {} 中以使其成为有效的 Json。所以我需要做的就是把所有东西都包装在 writer.WriteStartObject(); writer.WriteEndObject();修改了链接dotnetfiddle.net/OT4HKM处的代码感谢提供清晰
    猜你喜欢
    • 1970-01-01
    • 2019-05-07
    • 2016-11-21
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 2012-11-29
    • 1970-01-01
    相关资源
    最近更新 更多