Json.Net 反序列化数值的"NA"



我正在尝试使用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;
        }
    }
}
Json.NET允许您创建JsonConverter子类来处理特殊情况;覆盖一些方法并将其传递给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>()

相关内容

  • 没有找到相关文章

最新更新