aktualisieren
Ein Problem Deserializing unclosed object succeeds when the object has a parameterized constructor. #1038 wurde für diese Frage eröffnet. Es wurde in Json.NET release 10.0.1 im Änderungssatz 0721bd4 behoben.
Original-Antwort
Sie haben einen Fehler in Json.NET gefunden. Es tritt nur auf, wenn Ihr Objekt mit einem parametrisierten Konstruktor erstellt wird. Wenn ich das Objekt ändern, um einen nicht-parametrisierte Konstruktor habe:
public class CompletionDataRequest
{
public CompletionDataRequest(string text, int cursorPosition, string dataSource, string project)
{
Text = text;
CursorPosition = cursorPosition;
DataSource = dataSource;
Project = project;
}
[JsonConstructor]
private CompletionDataRequest()
{
}
[JsonProperty]
public string Text { get; private set; }
[JsonProperty]
public int CursorPosition { get; private set; }
[JsonProperty]
public string DataSource { get; private set; }
[JsonProperty]
public string Project { get; private set; }
}
Dann wird Json.NET richtig ein JsonSerializationException
werfen.
Die Ursache des Fehlers ist wie folgt. Beim Erstellen eines Objekts mit einem parameterlosen Konstruktor erstellt Json.NET zuerst das Objekt und füllt es dann mit JsonSerializerInternalReader.PopulateObject()
. Diese Methode hat die folgende (vereinfachte) Logik:
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id)
{
bool finished = false;
do
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
{
// Read and process the property.
}
case JsonToken.EndObject:
finished = true;
break;
case JsonToken.Comment:
// ignore
break;
default:
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
}
} while (!finished && reader.Read());
if (!finished)
{
ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object.");
}
return newObject;
}
Wie Sie sehen können, gibt es Logik if (!finished)
zu überprüfen, ob das Objekt tatsächlich geschlossen ist.
Wenn jedoch ein Objekt mit einem parametrisierte Konstruktor erstellen, werden die Eigenschaften zu lesen, bevor das Objekt aufgebaut ist, JsonSerializerInternalReader.ResolvePropertyAndCreatorValues()
mit:
private List<CreatorPropertyContext> ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
{
List<CreatorPropertyContext> propertyValues = new List<CreatorPropertyContext>();
bool exit = false;
do
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
// Read and process the property.
break;
case JsonToken.Comment:
break;
case JsonToken.EndObject:
exit = true;
break;
default:
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
}
} while (!exit && reader.Read());
return propertyValues;
}
Wie Sie gibt es keine gleichwertige Prüfung für exit
sehen kann wahr sein.
Ein Problem Deserializing unclosed object succeeds when the object has a parameterized constructor. #1038 wurde dafür geöffnet.
@ Łukasz - OK, ich ging voran und berichtete das Problem, [Deserializing nicht abgeschlossenes Objekt ist erfolgreich, wenn das Objekt einen parametrisierten Konstruktor hat. # 1038] (https://github.com/JamesNK/Newtonsoft.Json/issues/1038). – dbc
Oh, ich war in Arbeit, aber ich werde dann aufhören. Danke für die Hilfe –