使用自动修剪字符串反序列化json [英] Deserialize json with auto-trimming strings

查看:79
本文介绍了使用自动修剪字符串反序列化json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Newtonsoft.Json库

I use Newtonsoft.Json library

在反序列化期间是否可以从任何字符串数据中修剪空格?

Is there a way to trim spaces from any string data during deserialization?

class Program
{
    class Person
    {
        [JsonProperty("name")]
        public string Name;
    }
    static void Main(string[] args)
    {
        var p = JsonConvert.DeserializeObject<Person>(@"{ name: "" John "" }");
        Console.WriteLine("Name is: \"{0}\"", p.Name);
    }
}

已添加:

最后,我有了自定义转换器的解决方案.不好,但是最好使用Trim()属性.

Finally, I've got solution with custom converter. Not nice, but better then property with Trim().

如果有人有任何更自然的想法,欢迎您.

If anyone has any ideas how to do it in more natural way, please welcome.

class Program
{
    sealed class TrimAttribute : Attribute
    { }

    class TrimConverter<T> : JsonConverter where T : new()
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jObject = JObject.Load(reader);
            var obj = new T();
            serializer.Populate(jObject.CreateReader(), obj);

            var props = objectType.GetFields(BindingFlags.Instance | BindingFlags.Public)
                .Where(p => p.FieldType == typeof(string))
                .Where(p => Attribute.GetCustomAttributes(p).Any(u => (Type) u.TypeId == typeof(TrimAttribute)))
                ;

            foreach (var fieldInfo in props)
            {
                var val = (string) fieldInfo.GetValue(obj);
                fieldInfo.SetValue(obj, val.Trim());
            }

            return obj;
        }

        public override bool CanConvert(Type objectType)
        {
            return objectType.IsAssignableFrom(typeof (T));
        }
    }

    [JsonConverter(typeof(TrimConverter<Person>))]
    class Person
    {
        [JsonProperty("name")]
        [Trim]
        public string Name;

        [JsonProperty("surname")]
        public string Surname;
    }
    static void Main(string[] args)
    {
        var p = JsonConvert.DeserializeObject<Person>(@"{ name: "" John "", surname: "" Smith "" }");
        Console.WriteLine("Name is: \"{0}\", \"{1}\"", p.Name, p.Surname);
    }
}

推荐答案

您可以编写自己的

You could write your own JsonConverter:

public class TrimmingConverter : JsonConverter
{
    public override bool CanRead => true;
    public override bool CanWrite => false;

    public override bool CanConvert(Type objectType) => objectType == typeof(string);

    public override object ReadJson(JsonReader reader, Type objectType,
                                    object existingValue, JsonSerializer serializer)
    {
        return ((string)reader.Value)?.Trim();
    }

    public override void WriteJson(JsonWriter writer, object value, 
                                   JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

您可以像这样使用它来应用于所有字符串字段:

You can use it like this to apply to all string fields:

var json = @"{ name:"" John "" }"
var p = JsonConvert.DeserializeObject<Person>(json, new TrimmingConverter());
Console.WriteLine("Name is: \"{0}\"", p.Name);
//Name is: "John"

或者您可以将其仅应用于某些字段:

Or you can apply this to certain fields only:

public class Person
{
    [JsonProperty("name")]
    [JsonConverter(typeof(TrimmingConverter))] // <-- that's the important line
    public string Name { get; set; }
    [JsonProperty("other")]
    public string Other { get; set; }
}

var json = @"{ name:"" John "", other:"" blah blah blah "" }"
var p = JsonConvert.DeserializeObject<Person>(json);
Console.WriteLine("Name is: \"{0}\"", p.Name);
Console.WriteLine("Other is: \"{0}\"", p.Other);

//Name is: "John"
//Other is: " blah blah blah "

这篇关于使用自动修剪字符串反序列化json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆