【问题标题】:Could not convert string 'Name' to dictionary key type - Create a TypeConverter to convert from the string to the key type object无法将字符串“名称”转换为字典键类型 - 创建一个 TypeConverter 以从字符串转换为键类型对象
【发布时间】:2019-12-14 17:27:32
【问题描述】:

我正在尝试在json下面反序列化

  {
   "Settings": {
   "ServiceUrl": "http://www.somethingsample.sample",
   "FrequencyOfSchedulerInMinutes": 6    
  },

 "ApplicationLog": {
   "Serilog": {
      "MinimumLevel": "Information",
      "WriteTo": [
       {
        "Name": "RollingFile",
        "Args": {
           "pathFormat": "%PROGRAMDATALog.txt",
           "fileSizeLimitBytes": 10485760,
           "retainedFileCountLimit": 10,
           "rollingInterval": "Day",
           "outputTemplate": "== {Timestamp:yy}{Exception}"
       }
     }
    ]
   }
  }   
}

c# 类是

  public class Settings
  {
      [JsonProperty("ServiceUrl")]
      public string ServiceUrl { get; set; }

      [JsonProperty("FrequencyOfSchedulerInMinutes")]
      public int FrequencyOfSchedulerInMinutes { get; set; }

  }

  public class Args
  {
      [JsonProperty("pathFormat")]
      public string pathFormat { get; set; }

      [JsonProperty("fileSizeLimitBytes")]
      public int fileSizeLimitBytes { get; set; }

      [JsonProperty("retainedFileCountLimit")]
      public int retainedFileCountLimit { get; set; }

      [JsonProperty("rollingInterval")]
      public string rollingInterval { get; set; }

      [JsonProperty("outputTemplate")]
      public string outputTemplate { get; set; }
   }

   public class WriteTo
   {
      [JsonProperty("Name")]
      public string Name { get; set; }

      [JsonProperty("Args")]
      public Args Args { get; set; }
   }

   public class Serilog
   {
       [JsonProperty("MinimumLevel ")]
       public string MinimumLevel { get; set; }

       [JsonProperty("WriteTo")]
       public List<Dictionary<WriteTo, object>> WriteTo { get; set; }

   }

  public class ApplicationLog
  {
       [JsonProperty("Serilog")]
       public Serilog Serilog { get; set; }
  }

  public class RootObject
  {
      public Settings Settings { get; set; }
      public ApplicationLog ApplicationLog { get; set; }
  }

这是我的解析器

  class DictionaryAsArrayResolver : DefaultContractResolver
  {
    protected override JsonContract CreateContract(Type objectType)
    {
        if (objectType.GetInterfaces().Any(i => i == typeof(IDictionary) ||
                                                (i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>))))
        {
            return base.CreateArrayContract(objectType);
        }

        return base.CreateContract(objectType);
     }
  }

这就是我进行反序列化的方式

  JsonSerializerSettings settings = new JsonSerializerSettings();
  settings.ContractResolver = new DictionaryAsArrayResolver();

   var objectValue = JsonConvert.DeserializeObject<Dictionary<string, object>>(json, settings);
   var items = JsonConvert.DeserializeObject<RootObject>(objectValue.Values.First().ToString(), settings);

我遇到了错误

运行时异常(第 39 行):无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.Dictionary`2[System.String,System.Object ]' 因为该类型需要一个 JSON 数组(例如 [1,2,3])才能正确反序列化。 要修复此错误,要么将 JSON 更改为 JSON 数组(例如 [1,2,3]),要么将反序列化类型更改为普通的 .NET 类型(例如,不是像整数这样的原始类型,而不是像这样的集合类型可以从 JSON 对象反序列化的数组或列表。 JsonObjectAttribute 也可以添加到类型中以强制它从 JSON 对象反序列化。 路径“设置”,第 2 行,位置 13。

{"无法将字符串 'Name' 转换为字典键类型 'MyProject.WriteTo'。创建一个 TypeConverter 将字符串转换为键类型对象。路径 'ApplicationLog.Serilog.WriteTo[0].Name',第 21 行,第 17 位。"}

【问题讨论】:

  • 您的问题中没有显示AppSettings 类型,因此JsonConvert.DeserializeObject&lt;AppSettings&gt;(objectValue.Values.First().ToString(), settings); 无法编译。你能分享一个minimal reproducible example吗?另外,(objectValue.Values.First().ToString() 应该引用 JSON 的哪一部分?
  • @dbc 抱歉,这是错字。更新的问题。
  • @dbc 在此转载dotnetfiddle.net/1TLT4L

标签: c# json serialization json.net deserialization


【解决方案1】:

将对象WriteTo 作为字典键似乎有点奇怪。但是当将Serilog 更改为:

public class Serilog
{
    [JsonProperty("MinimumLevel ")]
    public string MinimumLevel { get; set; }

    [JsonProperty("WriteTo")]
    public List<WriteTo> WriteTo { get; set; }
}

可以在没有 ContractResolver 的情况下对其进行反序列化。

var rootObject = JsonConvert.DeserializeObject<RootObject>(json);

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-30
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 2023-02-08
相关资源
最近更新 更多