2016-10-10 41 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); 
} 

的varaible originalData内的JSON导致异常(下面详细说明)“无法设置属性‘RatioRight’与'null'“。 尽管'RatioRight'是'可空的单个','null'是一个有效的值,但这种情况发生。

删除scope.ThrowOnDeserializationError = true“工作”,但不是我们的选择,因为我们需要验证服务器端收到的数据。 我会解释一下,如果我们将ThrowOnDeserializationError设置为false(这是默认设置),则在此特定情况下不会抛出错误,但可以发送类似于此的json:{FlowRight:970045,RatioRight:fdfd} DeserializeFromString的结果不会抛出例外,尽管'fdfd'不是一个可空的单个。会发生什么情况是,异常将在内部处理,而空将被设置,导致服务器不知道发送的数据是无效的,并且稍后会导致保存空值而不是已经在db中的值(如我提到的,不能接受我们)

例外:

来源: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使用它采用CSV逃逸所以null值作为替代治疗JSV Format一个"null"字符串哪个不能转换为数字,导致错误。

要保留默认值,它应该从JSV发出,如:

var originalData = "{FlowRight:970045}"; 

如果你不是寻找一个JSON序列,你应该使用JsonSerializer,如:

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

哪可以使用扩展方法更简洁地重写,例如:

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