将json键值反序列化为字典c#

Posted

技术标签:

【中文标题】将json键值反序列化为字典c#【英文标题】:Deserialising json key-value into Dictionary c# 【发布时间】:2020-11-22 18:28:30 【问题描述】:

我在请求正文中有以下 JSON:


    "tableName": "ApiTestTbl",
    "columnsValues": 
        "test1": "value1",
        "column2": "value2"
    

我有这两个类:

public class InsertIntoDbEntity 

    public string tableName  get; set; 
    public InsertIntoDbColumnsValuesEntity columnsValues  get; set; 


public class InsertIntoDbColumnsValuesEntity

    public Dictionary<string, string> columnsValues  get; set; 

控制器功能如下:

[HttpPost]
[Route("app/singleinsert")]
public CrudReturnEntity InsertIntoDB(InsertIntoDbEntity entity)
        
    return null;

tableName 的值很好地分配了“ApiTestTbl”,但 columnsValues 始终为空。 我正在使用字典,因为未定义 columnValues 中键值对的数量,因此我想将它们存储在字典中进行处理。 谢谢!

【问题讨论】:

您是否有理由想要自定义 InsertIntoDbColumsValiesEntity 而不仅仅是直接将属性声明为 Dictionary&lt;string, string&gt;?因为你强迫另一个类在那里是什么使默认反序列化失败 是的,我需要这种方式,因为我希望 columnsValues 键对位于单独的 json 对象中,而不是在根对象中,例如 tableName。 @Knoop 你是对的!在我按照你的建议做了之后,我现在有了预期的结果。我不知道为什么我把事情复杂化了。谢谢! 【参考方案1】:

正如@Knoop 在 cmets 中建议的那样,在您的情况下,将 Dictionary 直接作为 InsertIntoDbEntity 模型的成员是相当简单的。

但是,如果您不具备这种可行性并且需要严格的结构,则可以通过以下方式解决。我们将为内部属性构建一个自定义 Json 转换器,使用 Newtonsoft.Json。

为内部属性创建自定义 JSON 转换器

public class MyInternalConverter : JsonConverter

    public override bool CanConvert(Type objectType)
    
        throw new NotImplementedException();
    

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    
        if(reader.TokenType == JsonToken.StartObject)
        
            JObject item = JObject.Load(reader);

            // You may want to perform any sanity checks you want here

            Dictionary<string, string> blah = JsonConvert.DeserializeObject<Dictionary<string, string>>(item.ToString());

            return new InsertIntoDbColumnsValuesEntity
            
                columnsValues = blah
            ;
        
        return null;
    

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    
        throw new NotImplementedException();
    

您还需要在模型中装饰属性以利用编写的自定义转换器。如下图所示完成

public class InsertIntoDbEntity

    public string tableName  get; set; 

    [JsonConverter(typeof(MyInternalConverter))]
    public InsertIntoDbColumnsValuesEntity columnsValues  get; set; 

基本上,可以在属性级别或类级别利用相同的技术,具体取决于自定义反序列化的需要。

【讨论】:

以上是关于将json键值反序列化为字典c#的主要内容,如果未能解决你的问题,请参考以下文章

使用JSON.Net将字符串属性值反序列化为类实例

Jackson 使用枚举键、POJO 值反序列化为 Map

使用 XmlSerializer 将空 xml 属性值反序列化为可为空的 int 属性

根据字段值反序列化为密封子类

将json反序列化为键值对列表[重复]

如何将多个键值条目的 JSON 对象反序列化为 Rust 中的自定义结构