从外部Web服务接收
// jsonWithConfig
// property config is an object {}
{"config":{"c1":"All","c2":"is peachy"},"message":"We found a config object"}
// jsonNoConfig
// property config is string with the value null
{"config":"null","message":"Config is null"}
我想将json反序列化为以下类型
public class WebResponse
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Config Config { get; set; }
public string Message { get; set; }
// i also tried dynamic but
// a) this is not what i want
// b) it resulted in RuntimeBinderException
// public dynamic Config { get; set; }
}
public class Config
{
public string C1 { get; set; }
public string C2 { get; set; }
}
我试过什么?
从How to ignore properties with System.Text.Json开始,我从System.Text.Json
开始使用JsonSerializer.Deserialize
var options = new JsonSerializerOptions{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNameCaseInsensitive = true
};
string jsonWithConfig =
{"config":{"c1":"All","c2":"is peachy"},"message":"We found a Config"}
WebResponse webResponseWithConfig =
JsonSerializer.Deserialize<WebResponse>(jsonWithConfig, options);
这适用于jsonWithConfig
,这并不奇怪,因为json可以反序列化为WebResponse
类型。
错误是什么?
我希望使用JsonSerializerOptions.DefaultIgnoreCondition可以用于jsonNoConfig = {"config":"null","message":"Config is null"}
,但是使用DeserializeUnableToConvertValue
时jsonNoConfig
的反序列化失败
string jsonNoConfig =
{"config":"null","message":"Config is null"}
WebResponse webResponseNoConfig =
JsonSerializer.Deserialize<WebResponse>(jsonNoConfig, options);
问题
- 我如何反序列化
jsonNoConfig
? - 我该怎么办?
更新
MySkullCaveIsADarkPlace指出config
的值应该是null
,而不是"null"
。更改后,上面的代码可以按预期工作。
但是有没有办法也处理带引号的null,比如{"config":"null", ...}
?
完整堆栈跟踪
linqpad内部的堆栈跟踪显示了这一点
在系统.文本. json.抛出助手.抛出jsonException_反序列化无法转换为值(类型属性类型)
at System. Text. Json. Serialization. Converters. ObjectDefaultConverter '1.OnTryRead(对象读取器和读取器、类型类型到转换、JsonSerializerOptions选项、读取堆栈和状态、T和值)
at系统.文本. Json.序列化. JsonConverter '1.TryRead(Utf8JsonReader和读取器,类型类型到转换,JsonSerializerOptions选项,读取堆栈和状态,T和值)
at系统.文本. Json.序列化.元数据. JsonPropertyInfo'1.读取JsonAndSetMember(对象对象,读取堆栈和状态,Utf8JsonReader和读取器)
at System. Text. Json. Serialization. Converters. ObjectDefaultConverter '1.OnTryRead(对象读取器和读取器、类型类型到转换、JsonSerializerOptions选项、读取堆栈和状态、T和值)
at系统.文本. Json.序列化. JsonConverter '1.TryRead(Utf8JsonReader和读取器,类型类型到转换,JsonSerializerOptions选项,读取堆栈和状态,T和值)
位于系统.文本. Json.序列化. JsonConverter '1.ReadCore(Utf8JsonReader和读取器、JsonSerializerOptions选项、读取堆栈和状态)
在系统.文本. Json. Json序列化程序.读取范围[T值](只读范围1 utf8Json, JsonTypeInfo jsonTypeInfo, Nullable
1实际字节计数)
在系统.文本. json. json串行化器. ReadFromSpan [TValue](只读跨度json,类型信息json类型信息)
位于UserQuery.Main()第13行的System.Text.Json.JsonSerializer.Deserialize [TValue](字符串json、JsonSerializerOptions选项)中
LINQPad程序
这个linqpad程序包含了所有需要的代码
// Linqpad program
void Main()
{
string jsonWithConfig = "{\"config\":{\"c1\":\"All\",\"c2\":\"is peachy\"},\"message\":\"We found a Config\"}";
string jsonNoConfig = "{\"config\":\"null\",\"Message\":\"Config is null\"}";
var options = new JsonSerializerOptions{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNameCaseInsensitive = true
};
WebResponse webResponseWithConfig = JsonSerializer.Deserialize<WebResponse>(jsonWithConfig, options);
webResponseWithConfig.Dump();
WebResponse webResponseNoConfig = JsonSerializer.Deserialize<WebResponse>(jsonNoConfig, options);
webResponseNoConfig.Dump();
}
// custom types
public class WebResponse
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public Config Config { get; set; }
public string Message { get; set; }
}
public class Config
{
public string C1 { get; set; }
public string C2 { get; set; }
}
2条答案
按热度按时间cl25kdpy1#
正如MySkullCaveIsADarkPlace在注解中所解释的,您的问题是JSON值
"null"
Isnot null。它是包含字符
null
的非空字符串值。空值如下所示:有关确认信息,请参见original JSON proposal。
如果您无法修复JSON以正确表示空值,则需要编写custom JsonConverter来检查
"null"
文本值并返回null
(如果存在)。如果不存在,则转换器应继续默认的反序列化。问题 How to use default serialization in a custom System.Text.Json JsonConverter? 有this answer,this answer提供了一个
DefaultConverterFactory<T>
,抓取它并将其子类化如下:空对象的空文本值转换器
默认转换器工厂
JSON序列化程序扩展
然后将转换器添加到
JsonSerializerOptions.Converters
,如下所示:或者直接应用于
Config
属性,如下所示:请注意,目前似乎没有一种方法可以生成一个默认的序列化,即直接将转换器应用于
Config
类型,因此,我不推荐这样做。演示小提琴here。
3xiyfsfu2#
如果您无法修复JSON源代码,那么在这种特殊情况下,我建议使用c#字符串替换函数将
"null"
替换为null