我正在尝试使用Json.Net反序列化数字数据,如果缺少值,则可能会将其指定为"NA",例如
{
"readings": [
{ "temperature" : 75 } ,
{ "temperature" : "NA" }
]
}
我想将这些值解析为双精度 类型,例如
public class Reading
{
public double? Temperature { get; set; }
}
其中(净效果),我的例子中的第一个读数是"75",第二个读数为"null"。
我无法控制提供给我的JSON。
JsonConverter是让Json.Net为我处理这个问题的唯一方法吗?还是有更简单的方法?(我总是可以为Json反序列化的值创建一个私有类变量,然后将我自己的公共属性添加到私有值中,该属性可以做我想做的任何事情,但由于我有很多属性要处理,这将需要大量额外的代码。)
我建议构建一个自定义类型转换器,但如果真的不想,可以实现一个忽略反序列化异常的错误处理程序。假设你有这样的设置:
public class Reading
{
public double? Temperature { get; set; }
}
public class Root
{
public List<Reading> Readings { get; set; }
}
你可以写这样的东西:
Root obj = JsonConvert.DeserializeObject<Root>(
json, new JsonSerializerSettings
{
Error = (sender, args) =>
{
Reading reading = args.CurrentObject as Reading;
if (reading != null && args.ErrorContext.Member.ToString() == "temperature")
{
reading.Temperature = null;
args.ErrorContext.Handled = true;
}
}
});
在这里,我们处理Error
事件,如果在反序列化temperature
成员时检测到错误,则标记已处理的错误。
万一你想使用自定义转换器,下面是它的样子:
public class NAConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Reading);
}
public override object ReadJson(
JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject obj = JObject.Load(reader);
Reading reading = new Reading();
string tempStr = obj.Value<string>("temperature");
double temp;
if (Double.TryParse(tempStr, out temp))
{
reading.Temperature = temp;
}
return reading;
}
public override void WriteJson(
JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
在服务器代码中,将temperature作为模型中的字符串,然后使用TryParse
查看它是否可以转换为double。
double tempValue;
if (Double.TryParse(yourObject.Temperature, out temp)){
// successfully parsed to a double
// do whatever you're going to do with the value
}
else {
// couldn't be parsed as a double, handle accordingly
}
https://msdn.microsoft.com/en-us/library/994c0zb1(v=vs.110).aspx
我认为没有办法让反序列化程序将字符串转换为可为null的双精度。最好将值反序列化为字符串,然后在使用时处理将字符串转换为数值的操作。
所以你可以试试这样的东西:
public class Reading
{
public string Temperature {get; set;}
private double? _NumTemperature;
public Double? NumTemperature{
get{ return _NumTemperature}
set{
Double n;
bool isNumeric = double.TryParse(Temperature, out n);
if (isNumeric)
{
_NumTemperature = n;
}
else
{
_NumTemperature = null;
}
}}
}
您可以如下修改您的类,并使用Newtonsoft Json库进行序列化/反序列化:
public class Reading
{
[JsonIgnore]
public double? Temperature { get; set; }
[JsonProperty("temperature")]
private string TemperatureString
{
get
{
return Temperature.HasValue ? Temperature.Value.ToString() :"NA";
}
set
{
double result;
Temperature = double.TryParse(value, out result) ? result : null;
}
}
}
JsonConvert.Deserialise*
方法
因此,您的步骤是创建一个大致类似的类;
public NAConverter: JsonConverter
{
public override bool CanConvert(Type t) { return t == typeof(string); }
public override ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
...
}
}
然后,在ReadJson中,您可以询问JsonReader是否指向字符串,以及它是否为"NA"。如果是,则返回null或zero或Double.IsNaN;否则,请服从基数。
然后将实例传递给JsonConvert.DeserializeObject()
或JsonConvert.Deserialize<T>()