对属性的 Json DeserializeObject 运行转换

Noc*_*tis 3 c# json.net

假设一个 json 字符串如下所示:

string json = '{"string_property":"foo_bar", ... other objects here ...}';
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一种方法可以对解析的对象运行转换,以便在运行以下方法后foo_bar我不会得到 ,而是得到(实际上可以是任何东西)foo bar

public string Transform(string s) {
    return s.Replace("_"," ");
}
Run Code Online (Sandbox Code Playgroud)

我可以在反序列化后手动更改我的poco,但想知道什么是“更干净”的方法?

dbc*_*dbc 5

您可以string在反序列化根对象时通过使用针对所有字符串类型值的自定义来转换属性:JsonConverter

public class ReplacingStringConverter : JsonConverter
{
    readonly string oldValue;
    readonly string newValue;

    public ReplacingStringConverter(string oldValue, string newValue)
    {
        if (string.IsNullOrEmpty(oldValue))
            throw new ArgumentException("string.IsNullOrEmpty(oldValue)");
        if (newValue == null)
            throw new ArgumentNullException("newValue");
        this.oldValue = oldValue;
        this.newValue = newValue;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(string);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var s = (string)JToken.Load(reader);
        return s.Replace(oldValue, newValue);
    }

    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

var settings = new JsonSerializerSettings { Converters = new[] { new ReplacingStringConverter("_", "") } };
var result = JsonConvert.DeserializeObject<RootObject>(json, settings);
Run Code Online (Sandbox Code Playgroud)

但请注意,如果各个字符串类型属性有自己的直接与 一起应用的转换器[JsonConverter(Type)],则这些转换器将优先于ReplacingStringConverter列表中的 来使用Converters