2016-10-10 4 views
1

Кажется, что есть ошибка в методе ServiceStack TypeSerializer.DeserializeFromString относительно обнуляемых типовServiceStack TypeSerializer.DeserializeFromString ошибка с C# типов обнуляемого

Это известная проблема? Есть ли исправление или обходное решение?

Рассмотрим следующий код, который включает в себя объем JsConfig, что для приведения в исполнение исключение бросание на какой-либо ошибки десериализации:

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); 
} 

JSON внутри Название переменной originalData вызывает исключение (подробно описано ниже) «Не удалось установить свойство„RatioRight“ с «нулем». Это происходит, несмотря на то, что RatioRight является «nullable single» и «null» является допустимым значением.

Удаление scope.ThrowOnDeserializationError = true «работает», но это не опция для нас, так как нам нужна проверка данных, полученных на стороне сервера. Я объясню, если мы установим ThrowOnDeserializationError в false (это значение по умолчанию), ошибка не будет выбрана в этом конкретном случае, но это позволит отправить json как этот: {FlowRight:970045,RatioRight:fdfd} результат DeserializeFromString не будет вызывать исключение, хотя «fdfd» не является ничтожным. Случилось бы так, что исключение будет обрабатываться внутренне, и вместо него будет установлено значение null, в результате чего сервер не будет знать, что отправленные данные недействительны и впоследствии приведет к сохранению нулевых значений вместо значений, уже находящихся в db (as я уже говорил, не приемлемы для нас)

Исключение:

Источник: 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

ответ

0

ServiceStack.Text в TypeSerializer использует JSV Format, который использует CSV Спасаясь поэтому значение null вместо этого рассматривается как a "null" строка, которая не может быть преобразован в число, вызывая ошибку.

Чтобы оставить значение по умолчанию должно быть излучаемый из JSV, например:

var originalData = "{FlowRight:970045}"; 

Если вы вместо ищете JSON Serializer вы должны использовать JsonSerializer, например:

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

Какие могут быть переписаны более кратко с использованием методов расширения, например:

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