2016-10-10 2 views
1

Es scheint, dass es ein Fehler in der ServiceStack Methode TypeSerializer.DeserializeFromString in Bezug auf Nullable Types istServiceStack TypeSerializer.DeserializeFromString Fehler mit C# Nullable Types

Ist das ein bekanntes Problem? Gibt es eine Behebung oder eine Umgehung?

den folgenden Code betrachten, die einen JsConfig Umfang enthält, die Ausnahme auszulösen auf jedem Deserialisierung Fehler erzwingt:

public class MeasurementsData 
{ 
    public int? FlowLeft { get; set; } 
    public int? FlowRight { get; set; } 
    public Single? RatioLeft { get; set; } 
    public Single? RatioRight { get; set; } 
} 
. 
. 
. 

var originalData = "{FlowRight:970045,RatioRight:null}"; 
object afterConversionData = null; 

try 
{ 
    using (var scope = JsConfig.BeginScope()) 
    { 
     scope.ThrowOnDeserializationError = true; 
     afterConversionData =TypeSerializer.DeserializeFromString(originalData.ToString() ,typeof(MeasurementsData)); 
    } 

} 
catch (System.Runtime.Serialization.SerializationException ex) 
{ 

    Logger.Warn("Service exception", ex); 
} 

Die json innerhalb des varaible originalData verursacht eine Ausnahme (unten beschrieben) „Failed Eigenschaft festlegen‚RatioRight‘ mit 'null' ". Dies geschieht trotz 'RatioRight' ist eine 'Nullable Single' und 'Null' ist ein gültiger Wert.

Entfernen scope.ThrowOnDeserializationError = true "funktioniert", ist aber keine Option für uns, da wir die Validierung der Daten auf der Serverseite erhalten müssen. Ich erkläre, wenn wir ThrowOnDeserializationError auf false setzen (das ist die Standardeinstellung), wird in diesem speziellen Fall kein Fehler ausgelöst, aber es würde senden ein JSON wie folgt: {FlowRight:970045,RatioRight:fdfd} würde das Ergebnis von DeserializeFromString nicht werfen Ausnahme, obwohl "fdfd" nicht einzeln als NULL-Zeichen zulässig ist. Was passieren würde, wäre, dass die Ausnahme intern behandelt würde und stattdessen null gesetzt würde, was dazu führen würde, dass der Server nicht weiß, dass die gesendeten Daten ungültig sind und später anstelle der bereits in der Datenbank gespeicherten Werte (anstatt ich erwähnte, nicht akzeptabel für uns)

die Ausnahme:

Quelle: ServiceStack.Text

Exception: Failed to set property 'MeasurementData' with '{FlowRight:970045,RatioRight:null}' InnerException: Failed to set property 'RatioRight' with 'null'

StackTrace: at ServiceStack.Text.Common.DeserializeTypeRefJsv.StringToType(TypeConfig typeConfig, String strType, EmptyCtorDelegate ctorFn, Dictionary'2 typeAccessorMap) at ServiceStack.Text.Common.DeserializeType'1.<>c__DisplayClass3.b__2(String value) at ServiceStack.Text.TypeSerializer.DeserializeFromString(String value, Type type) at Site.Service.Services.DataDomainService.Any(SaveDataDomainRequest request) in D:\Service\API Services\Domain\Services\DataDomainService.cs:line 93

Antwort

0

ServiceStack.Text des TypeSerializer verwendet die JSV Format die CSV verwendet Escaping so der null Wert wird stattdessen so behandelt, als eine "null" Zeichenfolge, die kann nicht in eine Zahl umgewandelt werden, was den Fehler verursacht.

den Standardwert lassen Sie es von der JSV, zB emittiert werden soll:

var originalData = "{FlowRight:970045}"; 

Wenn Sie stattdessen suchten einen JSON Serializer sollten Sie JsonSerializer, zB:

var afterConversionData = JsonSerializer.DeserializeFromString(
    originalData.ToString(), typeof(MeasurementsData)); 

Welche kann mit Extension-Methoden kürzer formuliert werden, zB:

var object = originalData.ToString().FromJson<MeasurementsData>();