C#JSON反序列化:我可以拦截反序列化和选择更改的结果? [英] C# JSON deserialization: can I intercept the deserialization and optionally change the result?
问题描述
我们已经有了一些JSON,我们反序列化到C#中的强类型的对象图。但是,我们有一个问题:有时会出现在该映射到我们的模型一个布尔值的属性的JSON(例如,空字符串)一个空值
We've got some JSON that we are deserializing into a strongly-typed object graph in C#. However, we've got one issue: sometimes there is an "empty" value in the JSON (e.g., empty string) in a property that maps to a boolean value in our model.
在我们的例子中,我们知道,100%的时间,我们可以把这些空白值布尔假
。
In our case, we know that 100% of the time, we can translate these "blank" values to Boolean false
.
不过,我已经试过了JSON解串器不知道这个(可以理解)。
However, the JSON deserializers I've tried don't know about this (understandably).
我一直试图找到一种方法拦截每个属性的反序列化,以及可选改写输出。也就是说,如果有一个拦截器的方法我可以注册,这是这样的:
I've been trying to find a way to intercept the deserialization of each property, and optionally override the output. I.e., if there was an "interceptor" method I could register, that looked like this:
public Boolean JsonDeserializationInterceptor(String rawJson, System.Type targetType, out object result)
{
Boolean overrodeValue = false;
result = null;
if(targetType == typeof(System.Boolean))
{
overrodeValue = true;
// We'll pretend that we're interpreting the string "Yes" as
// true, and all other values are false.
if (rawJson != null && rawJson.ToLower() == "\"yes\"")
result = true;
else
result = false;
}
return overrodeValue;
}
这只是假设,当然,但我希望它给你的想法是什么我试图完成的任务。
That's just hypothetical, of course, but hopefully it gives you an idea of what I'm trying to accomplish.
在我的研究,我一直没能想出一个办法做到这一点。我看着 Json.NET ,的 System.Runtime.Serialization.Json.DataContractJsonSerializer 和的System.Web.Script.Serialization.JavaScriptSerializer 。我敢打赌,有一种方法可以做到这一点,我只是一直没能弄明白。
In my research I have not been able to figure out a way to do this. I've looked at Json.NET, System.Runtime.Serialization.Json.DataContractJsonSerializer, and System.Web.Script.Serialization.JavaScriptSerializer. I bet there is a way to do this, and I just haven't been able to figure it out.
修改:我想你也许能够使用的 JsonConverterAttribute ,但到目前为止,我还没有能够得到那个工作。
Edit: I think you might be able to use the JsonConverterAttribute, but so far I have not been able to get that working.
推荐答案
编写自定义 JsonConverter
为基本类型是非常straghtforward:
Writing a custom JsonConverter
for a primitive type is pretty straghtforward:
using System;
using Newtonsoft.Json;
namespace So16972364JsonDeserializeConverter
{
class BoolConverter : JsonConverter
{
public override void WriteJson (JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
public override object ReadJson (JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType) {
case JsonToken.String:
if ((string)reader.Value == "")
return false;
break;
case JsonToken.Boolean:
return reader.Value;
}
throw new JsonReaderException("Expected boolean or empty string.");
}
public override bool CanConvert (Type objectType)
{
return objectType == typeof(bool);
}
}
class Program
{
const string json = @"
{
b1: true,
b2: false,
b3: ''
}
";
static void Main ()
{
Foo foo = JsonConvert.DeserializeObject<Foo>(json, new JsonSerializerSettings {
Converters = { new BoolConverter() }
});
Console.WriteLine(JsonConvert.SerializeObject(foo, Formatting.Indented));
Console.ReadKey();
}
}
class Foo
{
public bool b1, b2, b3;
}
}
这代码覆盖所有的布尔值的反序列化。如果您需要此只对特定的成员,您需要申请 JsonConverterAttribute
。
This code overrides deserialization of all boolean values. If you need this only for specific members, you need to apply JsonConverterAttribute
.
这篇关于C#JSON反序列化:我可以拦截反序列化和选择更改的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!