2014-11-21 24 views
3

我需要创建一个遗留系统的自定义JSON.NET转换器,标志空十进制值与...定制JsonConverter可以decimal.MinValue转换为空字符串和背部

var nulldec = decimal.MinValue; 

(这是创建在可空类型被引入之前,并且改变这种工作方式将是一大堆工作。)

当这些最小值序列化为JSON时,它们需要序列化为空字符串。当它们被反序列化时,如果该值为空字符串,则需要转换为decimal.MinValue

这是我到目前为止(是的,没有太多)。我认为这是一个简单的转换,但我没有看到任何文章指出我如何为我的情况工作,也没有关于如何创建自定义转换器的任何文档。有人可以帮忙吗?

public class DecimalJsonConverter : JsonConverter 
{ 
    public override object ReadJson(JsonReader reader, Type objectType, 
            object existingValue, JsonSerializer serializer) 
    { 
    } 
    public override void WriteJson(JsonWriter writer, object value, 
            JsonSerializer serializer) 
    { 
    } 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(System.Decimal).IsAssignableFrom(objectType); 
    } 
} 

回答

5

下转换器实现应该给你你想要的东西:

public class DecimalJsonConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(decimal)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, 
            object existingValue, JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.String) 
     { 
      if ((string)reader.Value == string.Empty) 
      { 
       return decimal.MinValue; 
      } 
     } 
     else if (reader.TokenType == JsonToken.Float || 
       reader.TokenType == JsonToken.Integer) 
     { 
      return Convert.ToDecimal(reader.Value); 
     } 

     throw new JsonSerializationException("Unexpected token type: " + 
              reader.TokenType.ToString()); 
    } 

    public override void WriteJson(JsonWriter writer, object value, 
            JsonSerializer serializer) 
    { 
     decimal dec = (decimal)value; 
     if (dec == decimal.MinValue) 
     { 
      writer.WriteValue(string.Empty); 
     } 
     else 
     { 
      writer.WriteValue(dec); 
     } 
    } 
} 

这是一个往返演示:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string json = @" 
     { 
      ""MinValueAsString"" : """", 
      ""ARealDecimal"" : 3.14159, 
      ""AnInteger"" : 42 
     }"; 

     JsonSerializerSettings settings = new JsonSerializerSettings(); 
     settings.Converters.Add(new DecimalJsonConverter()); 
     settings.Formatting = Formatting.Indented; 

     Foo foo = JsonConvert.DeserializeObject<Foo>(json, settings); 

     Console.WriteLine("MinValueAsString: " + foo.MinValueAsString); 
     Console.WriteLine("ARealDecimal: " + foo.ARealDecimal); 
     Console.WriteLine("AnInteger: " + foo.AnInteger); 
     Console.WriteLine(); 

     json = JsonConvert.SerializeObject(foo, settings); 
     Console.WriteLine(json); 
    } 

    class Foo 
    { 
     public decimal MinValueAsString { get; set; } 
     public decimal ARealDecimal { get; set; } 
     public decimal AnInteger { get; set; } 
    } 
} 

输出:

MinValueAsString: -79228162514264337593543950335 
ARealDecimal: 3.14159 
AnInteger: 42 

{ 
    "MinValueAsString": "", 
    "ARealDecimal": 3.14159, 
    "AnInteger": 42.0 
} 

小提琴:https://dotnetfiddle.net/dip85r

+0

没问题;乐意效劳。 – 2014-11-21 18:54:23

+0

非常感谢代码@BrianRogers – IgorShch 2016-01-21 11:41:05