Zauważam, że istnieją inne wyniki na stackoverflow dla tego pytania, ale nie wydają się działać lub są niejasne. Korzystając z najbardziej popularnego wyniku, zestawiłem to:Jak używać JSON.NET do obsługi wartości, która jest czasem obiektem, a czasem tablicą obiektu?
Problem polega na tym, że gdy JSON wraca i jest serializowany do jednego z moich niestandardowych typów, jeden z bitów JSON jest czasem tablicą, a czasem tylko strunowy. Jeśli mój typ niestandardowy ma ciąg znaków, a JSON jest tablicą, pojawia się błąd. To samo dzieje się na odwrót, jeśli JSON jest obiektem, a moim niestandardowym typem jest tablica. Po prostu nie można go zmapować do nieruchomości.
Postanowiłem rozwiązać ten problem, chcę nadpisać deserializację tej konkretnej właściwości, a jeśli jest to obiekt, chcę przekształcić go w tablicę 1 obiektu.
W obiekcie, do którego szykuję, dodałem JsonConverter, który moim zdaniem zastąpi sposób, w jaki jest deserializowany.
[JsonConverter(typeof(ArrayOrSingleObjectConverter<string>))]
public List<string> person { get; set; }
Pomysł polega na tym, że niestandardowy konwerter przekształci pojedynczy obiekt w tablicę. Jeśli więc JSON to "Hello", ustawi on osobę na Listę zawierającą "Hello" zamiast rzucania wyjątku mówiącego, że nie można przekonwertować napisu na Listę.
Jeśli to już tablica, powinna po prostu zostawić ją w spokoju.
Konwerter wygląda następująco:
public class ArrayOrSingleObjectConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true; // Not sure about this but technically it can accept an array or an object, so everything is game.
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (objectType == typeof(List<T>))
{
return serializer.Deserialize<List<T>>(reader);
}
else
{
var singleObject = serializer.Deserialize<T>(reader);
var objectAsList = new List<T>();
objectAsList.Add(singleObject);
return objectAsList;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
To nie działa. Powyższy kod generuje wyjątek, próbując deserializować pojedynczy ciąg znaków, mówiąc, że nie może go wrzucić do listy wewnątrz instrukcji if ("objectype" jest jednak listą).
Staram się zrozumieć, co dokładnie robią metody odczytu i zapisu. W drugiej odpowiedzi na stackoverflow sugeruje wyrzucenie NotImplementedException
w metodzie odczytu. Ale jeśli to zrobię, wywoływana jest metoda odczytu, a wyjątek wyrzuca.
Myślę, że jestem na dobrej drodze, ale potrzebuję szturchnięcia we właściwym kierunku. Myślę, że jestem nieco zdezorientowany tym, co robi metoda ReadJSon i jakie są jej parametry.
Nie do końca rozumiem, skąd pochodzi wartość, ponieważ deserializuje się, ponieważ nie określiłem jej w wywołaniu metody Deserialize.
Jestem trochę zagubiony w tej sprawie.
Nie możesz deserializować obiektu "zmiennego" do "System.Object"? Możesz wtedy sprawdzić typ czasu wykonywania i zrobić swoje. –