Newtonsoft PopulateObject - 值不能为空异常
Newtonsoft PopulateObject - Value Cannot be Null Exception
我正在尝试填充自定义可枚举的现有实例,该实例包含包含 enum
属性的对象。当我这样做时,我收到来自 JsonConvert.PopulateObject()
的错误 System.ArgumentNullException: Value cannot be null
。是什么原因造成的?这是我的示例:
https://dotnetfiddle.net/CLYN3L
我想看看是否有以下原因:
我的 class 中有枚举。
我的class继承了IEnumerator
,IEnumerable
.
我有以下 classes 和枚举,我无法控制。我无法更改它们:
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>
并实现必要的泛型方法,从而通知 Json.NET 项目类型和Add()
方法,但不幸的是你声明
I cannot change them [the classes].
因此,最简单的解决方法是填充基础列表:
Newtonsoft.Json.JsonConvert.PopulateObject(json, resultDTO.ErrorList);
演示 fiddle here.
我正在尝试填充自定义可枚举的现有实例,该实例包含包含 enum
属性的对象。当我这样做时,我收到来自 JsonConvert.PopulateObject()
的错误 System.ArgumentNullException: Value cannot be null
。是什么原因造成的?这是我的示例:
https://dotnetfiddle.net/CLYN3L
我想看看是否有以下原因:
我的 class 中有枚举。
我的class继承了
IEnumerator
,IEnumerable
.
我有以下 classes 和枚举,我无法控制。我无法更改它们:
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>
并实现必要的泛型方法,从而通知 Json.NET 项目类型和Add()
方法,但不幸的是你声明
I cannot change them [the classes].
因此,最简单的解决方法是填充基础列表:
Newtonsoft.Json.JsonConvert.PopulateObject(json, resultDTO.ErrorList);
演示 fiddle here.