c# - Newtonsoft PopulateObject - 值不能为空异常

标签 c# json.net populate

我正在尝试填充自定义枚举的现有实例,该实例包含包含 enum 属性的对象。当我这样做时,我从 JsonConvert.PopulateObject() 收到错误 System.ArgumentNullException: Value cannot be null。是什么原因造成的?这是我的示例:

https://dotnetfiddle.net/CLYN3L

我正在尝试查看是否有以下任何原因:

  1. 我的类(class)有枚举。

  2. 我的类继承IEnumeratorIEnumerable

我有以下我无法控制的类和枚举。我无法更改它们:

public enum ErrorDisplayType : int 
{
    PopUp = 0,
    ErrorPane = 1,
    Statusbar = 2
}

[Serializable()]
public class ErrorObj 
{
   private string errorCode;
   private ErrorDisplayType errorDispType;

   public string ErrorCode 
   {
     get { return this.errorCode; }
     set {
        this.errorCode = value;
        if (errorCode != null)
        {
           this.setFields(errorCode);
        }
     }
   }
   public ErrorDisplayType ErrorDispType 
   {
      get { return this.errorDispType; }
      set { this.errorDispType = value; }
   }

    private void setFields(string errorCode) 
    {
       this.errorDispType = (ErrorDisplayType)int.Parse(errorCode);
    }   
}

[Serializable]
public class ErrorDTO : IEnumerator, IEnumerable 
{
   private int indx = -1;
   private List<ErrorObj> errorList;

   public List<ErrorObj> ErrorList 
   {
     get { return this.errorList; }
     set { this.errorList = value; }
   }

   public ErrorDTO()
   {
        this.errorList = new List<ErrorObj>();
   }

   public int Add(ErrorObj error)
   {
    this.errorList.Add(error);
    return 0;  
   }

   public bool MoveNext()
   {
      if (indx < errorList.Count - 1)      
      {                                    
         ++indx;                          
         return true;                     
      }                                    
      else                                 
      {                                    
         indx = -1;                       
         return false;                    
      }                                    
    }

    public void Reset()
    {
      this.indx = -1;
    }

    public object Current                                                            
    {                                                                               
       get                                                                          
       {                                                                            
         if (errorList.Count == 0 || indx < 0 || indx > errorList.Count - 1)
         { 
            return null;                                                         
         }
         return this.errorList[indx];                                             
       }                                                                            
    } 
    public IEnumerator GetEnumerator()  
    {
      return (IEnumerator)this;
    }

}

我有方法(我无法更改)给我如下所示的 JSON 字符串

[{
    "ErrorCode": "ABCD125",
    "ErrorDispType": 1
}]

我生成如下:

// below is already existing code
private static ErrorObj CreateErrorObj(string errorCode)
{
   ErrorObj error = new ErrorObj();
   error.ErrorCode = "ABCD125";
   error.ErrorDispType = (ErrorDisplayType)int.Parse(errorCode);
   return error;    
}

public string GetErrorJSON()
{
  ErrorDTO errDTO = new ErrorDTO();
  ErrorObj errObj = CreateErrorObj("1");
  errDTO.Add(errObj);

  string returnValue = Newtonsoft.Json.JsonConvert.SerializeObject(errDTO);
  return returnValue;
 }

下面是我的代码,我正在尝试反序列化

ErrorDTO errorDTO = new ErrorDTO();
string jsonString = GetErrorJSON();

下面一行抛出错误。 System.ArgumentNullException:值不能为空。

Newtonsoft.Json.JsonConvert.PopulateObject(jsonString, errorDTO);

请告诉我问题是什么。如果您需要更多信息,请告诉我。

最佳答案

您的基本问题是您已声明 ErrorDTO作为IEnumerator, IEnumerable ,也就是说一个无类型的、非泛型的可枚举。 Json.NET 将此类对象解释为只读无类型集合,因此当您尝试填充它时,会出现异常:

System.ArgumentNullException: Value cannot be null.
   at System.RuntimeType.MakeGenericType(Type[] instantiation)
   at Newtonsoft.Json.Serialization.JsonArrayContract.CreateWrapper(Object list)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Populate(JsonReader reader, Object target)
   at Newtonsoft.Json.JsonSerializer.PopulateInternal(JsonReader reader, Object target)
   at Newtonsoft.Json.JsonConvert.PopulateObject(String value, Object target, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.PopulateObject(String value, Object target)

异常消息没有用且具有误导性,但真正的原因是 Json.NET 无法知道要反序列化的集合项目的目标类型,或者反序列化后添加它们的方法,因为任何无类型的只读集合。

解决此类问题的正常方法是声明 ErrorDTO作为ICollection<ErrorObj>并实现必要的通用方法,从而将项目类型和 Add() 通知给 Json.NET方法,但不幸的是你说

I cannot change them [the classes].

因此,最简单的解决方法是填充基础列表:

Newtonsoft.Json.JsonConvert.PopulateObject(json, resultDTO.ErrorList);

演示 fiddle here .

关于c# - Newtonsoft PopulateObject - 值不能为空异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54207670/

相关文章:

c# - unescape后如何转义嵌入式JSON

node.js - 如何在模式数组中发布和更新模式并打印它?

c# - 在 sqlite 数据库上实现全文搜索的最有效方法是什么

c# - 从网络摄像头抓取图像时,使用 XNA 渲染位图很慢,为什么?

c# - 序列化属性,但不要反序列化 Json.Net 中的属性

arrays - 从单数组数据和多个部分填充 tableView

android - 使用图像完全填充 GridView,无需填充

c# - 无法连接到 MySql 数据库 - "SELECT command denied for user [...]"

c# - 在 C# 中设置文件的 UAC 设置

c# - 反序列化运行时创建的类