Newtonsoft Json 将值 null 转换为类型“System.Int32”时出错

Posted

技术标签:

【中文标题】Newtonsoft Json 将值 null 转换为类型“System.Int32”时出错【英文标题】:Newtonsoft Json Error converting value null to type 'System.Int32'Newtonsoft Json 将值 null 转换为类型“System.Int32”时出错 【发布时间】:2017-06-11 21:55:05 【问题描述】:

执行 AJAX 请求时出现以下错误:

将值 null 转换为类型“System.Int32”时出错。路径“[5].tabID”,第 1 行,位置 331。

错误出现在我的processRequest (...)第二行

public void ProcessRequest (HttpContext context)  
    string strJson = new StreamReader(context.Request.InputStream).ReadToEnd();
    List<ElementToUpdate> elements = JsonConvert.DeserializeObject<List<ElementToUpdate>>(strJson);

    // (...)

调试器说这是strJson的内容:

[
    "bmk": "132M1",
    "state": "off",
    "type": "motor",
    "tabID": 8
, 
    "bmk": "158M1",
    "state": "off",
    "type": "motor",
    "tabID": 8
, 
    "bmk": "194M1",
    "state": "off",
    "type": "motor",
    "tabID": 8
, 
    "bmk": "198M1",
    "state": "on",
    "type": "motor",
    "tabID": 8
, 
    "bmk": "202M1",
    "state": "off",
    "type": "motor",
    "tabID": 8
, 
    "bmk": "test-m",
    "state": "on",
    "type": "motor",
    "tabID": null
, 
    "bmk": "158M1-2",
    "state": "off",
    "type": "motor",
    "tabID": 2
, 
    "bmk": "100M1",
    "state": "on_right",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "152M1",
    "state": "on",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "192M1",
    "state": "on_left",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "196M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "2000M1",
    "state": "on_left",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "74M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "76M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "80M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "82M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "86M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "90M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "94M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "95M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "96M1",
    "state": "off",
    "type": "screwconveyor",
    "tabID": 8
, 
    "bmk": "102Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "104Y1",
    "state": "open",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "112Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "114Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "120Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "122Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "128Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "146Y1_2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "148Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "156Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "180Y1",
    "state": "open",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "182Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "184Y1",
    "state": "open",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "206Y1",
    "state": "open",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "208Y1",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "72Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "78Y2",
    "state": "open",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "84Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "88Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "92Y2",
    "state": "closed",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "95_1Y1",
    "state": "blocked",
    "type": "ventile",
    "tabID": 8
, 
    "bmk": "17H1",
    "state": "on",
    "type": "lamp",
    "tabID": 8
, 
    "bmk": "l1",
    "state": "on",
    "type": "lamp",
    "tabID": 8
, 
    "bmk": "17H1-2",
    "state": "on",
    "type": "lamp",
    "tabID": 2
, 
    "bmk": "106M1",
    "state": "on",
    "type": "elevator",
    "tabID": 8
, 
    "bmk": "154M1",
    "state": "off",
    "type": "elevator",
    "tabID": 8
, 
    "bmk": "164M1",
    "state": "off",
    "type": "rotaryvalve",
    "tabID": 8
]

ElementToUpdate 类是

public class ElementToUpdate

public ElementType type;
public String bmk;
public string state;
public int tabID;

public ElementToUpdate()



public ElementToUpdate(ElementType type, String bmk, string state, int tabID)

    this.type = type;
    this.bmk = bmk;
    this.state = state;
    this.tabID = tabID;


所以我的问题是:如何解决这个问题?如果我正确理解错误消息,那么它会说序列化数组中第 5 个 json 对象的tabIDnull。但正如你所看到的,事实并非如此。此外,ElementToUpdate.tabID 不是Int32,而是int。我错过了什么吗?

解决方案

事实上,我的 JSON 字符串包含一个元素,其 tabIDnull。我不知何故忽略了这一点,因为首先我的 JSON 字符串在我检查时没有格式化,其次因为 [5] 表示“数组的第 6 个元素”(我声称实际上知道)。

【问题讨论】:

int = Int32。以防万一...C#, int or Int32? Should I care? @MelanciaUK 我也是这么想的。但是错误信息让我不确定... 我编辑了问题以扩展 JSON 字符串,这样更容易看出问题出在哪里。 【参考方案1】:

使您的 tabID 可以为空:

public int? tabID;

null 无法反序列化为整数。 这是 json 的第 6 部分(或从 0 开始的第 5 部分):

\"bmk\":\"test-m\",\"state\":\"on\",\"type\":\"motor\",\"tabID\":null

你可以看到,tabID 在那里是空的。

【讨论】:

显然在我作为 JSON 数组 tabID 传递的所有对象中都没有。 @elementzero23 您的 JSON 中的 tabID 之一为空,或者它被序列化为空,或者您的序列化错误。 感谢您保持原样回答。我不知道这种事情是可能的。 必须使我的所有视图模型的属性都可以为空以避免这个问题似乎是错误的解决方法。 更改模型定义并不总是一种选择【参考方案2】:

根据您的用例,您可能还需要考虑使用JSON Serializer ignore nulls

例子:

Movie movie = new Movie();
movie.Name = "Bad Boys III";
movie.Description = "It's no Bad Boys";

string included = JsonConvert.SerializeObject(movie,
    Formatting.Indented,
    new JsonSerializerSettings  );

// 
//   "Name": "Bad Boys III",
//   "Description": "It's no Bad Boys",
//   "Classification": null,
//   "Studio": null,
//   "ReleaseDate": null,
//   "ReleaseCountries": null
// 

string ignored = JsonConvert.SerializeObject(movie,
    Formatting.Indented,
    new JsonSerializerSettings  NullValueHandling = NullValueHandling.Ignore );

// 
//   "Name": "Bad Boys III",
//   "Description": "It's no Bad Boys"
// 

【讨论】:

var serializerSettings = new JsonSerializerSettings NullValueHandling = NullValueHandling.Ignore ; 这是最好的答案。将模型属性更改为可为空并不总是一种选择 我同意@LastTribunal,尝试了很多次(11 次测试),除了 paulschoeder 的设置 这应该标记为正确答案,因为如果我们开始实时将数据类型更改为可为空,则可能会更改n个位置。至少在我的情况下,我需要更改 50 多个地方,我们需要在已经使用不可为空实现的任何地方输入大小写。所以这对我来说是更合适的解决方案,

以上是关于Newtonsoft Json 将值 null 转换为类型“System.Int32”时出错的主要内容,如果未能解决你的问题,请参考以下文章

C#如何Json转字符串;字符串转Json;Newtonsoft.Json(Json.Net)

使用Newtonsoft将DataTable转Json

Asp.net C# 使用Newtonsoft.Json 实现DataTable转Json格式数据

Newtonsoft.Json把含有集合的对象转换成json

转:Newtonsoft.Json高级用法

屌丝技能--转Json(Newtonsoft.Json.dll)