From an external webservice i receive either
// 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"}
I want to deserialize the json into these types
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; }
}
What have i tried?
From How to ignore properties with System.Text.Json i started with JsonSerializer.Deserialize from System.Text.Json
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);
This works for jsonWithConfig
which is no surprise since the json can be deserilized to the type WebResponse
.
What is the error?
I hoped that using JsonSerializerOptions.DefaultIgnoreCondition would work for jsonNoConfig = {"config":"null","message":"Config is null"}
.
But deserialization of jsonNoConfig
fails with DeserializeUnableToConvertValue
string jsonNoConfig =
{"config":"null","message":"Config is null"}
WebResponse webResponseNoConfig =
JsonSerializer.Deserialize<WebResponse>(jsonNoConfig, options);
Questions
- How can i deserialize
jsonNoConfig
? - What must i do?
Update
MySkullCaveIsADarkPlace pointed out that config
should have the value null
and not "null"
. After changing this the code above works as expected.
But is there a way to handle null with quotation marks like {"config":"null", ...}
as well?
Full stack trace
The stack trace inside linqpad shows this
at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan
1 utf8Json, JsonTypeInfo jsonTypeInfo, Nullable
1 actualByteCount)at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo jsonTypeInfo)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options) at UserQuery.Main(), line 13
LINQPad program
This linqpad-program has all the code needed
// 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; }
}