У меня есть требование для некоторой десериализации, которую я пытаюсь обработать, где я мог бы иметь эти потенциальные входы:
{
"value": "a string"
}
- или -
{
"value": {
"text": "a string"
// there are other properties, but for successful deserialization I only need text present
}
}
И я ожидаю чтобы иметь возможность успешно преобразовать в объект, MyObject
:
public class MyObject
{
[JsonProperty("text")
public string Text { get; set; }
}
Пока это то, что у меня есть в моем конвертере. Этот случай отлично работает, когда это строка (хотя и не очень эффективно, потому что я генерирую исключение, чтобы поймать неудачную десериализацию). Однако, когда это объект, читатель выдает исключение, и я не знаю, как с этим справиться.
public class MyObjectConverter : JsonConverter
{
public override bool CanWrite { get => false; }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string) || objectType == typeof(MyObject);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var value = reader.Value?.ToString();
if (string.IsNullOrWhiteSpace(value))
{
return null;
}
try
{
return JObject.Parse(value).ToObject<MyObject>();
}
catch (Exception)
{
return new MyObject
{
Text = value
};
}
}
}
возможно, у меня уже есть хороший способ сделать это, о котором я не знаю ? Если нет, как я могу определить, является ли мой ввод строкой или объектом, чтобы иметь возможность вернуть объект, который мне небезразличен?
РЕШЕНИЕ:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
{
return new MyObject
{
Text = reader.Value?.ToString()
};
}
else if (reader.TokenType == JsonToken.StartObject)
{
JObject obj = JObject.Load(reader);
return obj.ToObject<MyObject>();
}
else
{
return null;
}
}