如何处理空/空值在 JsonConvert.derializeObject

我有以下密码:

return (DataTable)JsonConvert.DeserializeObject(_data, (typeof(DataTable)));

然后,我试着:

var jsonSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};


return (DataTable)JsonConvert.DeserializeObject<DataTable>(_data, jsonSettings);

返回行抛出了错误:

{“错误转换值”类型为“ System.Double”。“}

网上有很多解决方案建议使用可空类型创建自定义 Class,但这对我来说不起作用。我不能指望 json 是某种格式的。我无法控制列计数、列类型或列名。

143140 次浏览

You can subscribe to the 'Error' event and ignore the serialization error(s) as required.

    static void Main(string[] args)
{
var a = JsonConvert.DeserializeObject<DataTable>("-- JSON STRING --", new JsonSerializerSettings
{
Error = HandleDeserializationError
});
}


public static void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
{
var currentError = errorArgs.ErrorContext.Error.Message;
errorArgs.ErrorContext.Handled = true;
}

You can supply settings to JsonConvert.DeserializeObject to tell it how to handle null values, in this case, and much more:

var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
var jsonModel = JsonConvert.DeserializeObject<Customer>(jsonString, settings);

An alternative solution for Thomas Hagström, which is my prefered, is to use the property attribute on the member variables.

For example when we invoke an API, it may or may not return the error message, so we can set the NullValueHandling property for ErrorMessage:


public class Response
{
public string Status;


public string ErrorCode;


[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string ErrorMessage;
}




var response = JsonConvert.DeserializeObject<Response>(data);

The benefit of this is to isolate the data definition (what) and deserialization (use), the deserilazation needn’t to care about the data property, so that two persons can work together, and the deserialize statement will be clean and simple.

ASP.NET CORE: The accepted answer works perfectly. But in order to make the answer apply globally, in startup.cs file inside ConfigureServices method write the following:

    services.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});

The answer has been tested in a .Net Core 3.1 project.