Проблема не в том, что ваш ApiErrorConverter имеет конструктор, а в том, как вы вызываете значение свойства json для метода объекта. Поскольку вы передаете сериализатор, он снова вызывает метод ReadJson для свойства. Это терпит неудачу во втором свойстве (строке), поскольку строка не имеет конструктора без параметров. Если вы используете перегрузку ToObject, которая просто указывает тип, она будет работать. Учитывая предоставленный образец данных, вам также нужно проверить NULL в PropertyInfo перед его использованием.
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object instance = Activator.CreateInstance(objectType);
var props = objectType.GetTypeInfo().DeclaredProperties.ToList();
JObject jo = JObject.Load(reader);
foreach (JProperty jp in jo.Properties())
{
if (!_propertyMappings.TryGetValue(jp.Name, out var name))
name = jp.Name;
PropertyInfo prop = props.FirstOrDefault(pi =>
pi.CanWrite &&
pi.GetCustomAttribute<JsonPropertyAttribute>().PropertyName == name);
prop?.SetValue(instance, jp.Value.ToObject(prop.PropertyType));
}
return instance;
}
Ответ на дополнительные комментарии:
Был задан вопрос, учитывая другую структуру json:
string payload2 = "{\"statusCode\":123,\"code\":\"error_code\",\"name\":\"hahaha\",\"description\":\"The Message\",\"qqqitem\":[{\"ahah\":\"cl\",\"ahahah\":\"item\"}]}";
Как получить массив с именем qqqitem в мой десериализованный объект?
Во-первых, массив - это объект с двумя свойствами: ахах и ахахах, для этого нам нужно создать класс. Я назову это Item.
public class Item
{
public string ahah { get; set; }
public string ahahah { get; set; }
}
Тогда нам нужно, чтобы наш класс ApiError содержал массив этих объектов. Я создам его в виде списка.
public class ApiError
{
[JsonProperty("error")]
public string Error { get; set; }
[JsonProperty("errorCode")]
public string ErrorCode { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("statusCode")]
public int StatusCode { get; set; }
[JsonProperty("items")]
public List<Item> Items { get; set; }
}
Наконец, поскольку имена не совпадают, я добавлю отображение
Dictionary<string, string> test = new Dictionary<string, string>
{
{"name", "error"},
{"code", "errorCode"},
{"description", "message"},
{"qqqitem", "items"}
};