如果该值为null,则Json.NET不会调用我的自定义转换器 [英] Json.NET not call my custom converter if that value is null

查看:83
本文介绍了如果该值为null,则Json.NET不会调用我的自定义转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题困扰了我一天. 我创建的自定义转换器会将空字符串转换为空字符串. 我发现,如果字符串的值为空,则Json.NET不会调用我的转换器. 我尝试设置所有可以设置的内容,但Json.NET仍未将空字符串发送到自定义转换器. 这是我的转换器代码

I am stuck with this problem for a day. The custom converter that I created will convert null string to empty string. I found that if the string has null value Json.NET not call my converter. I 've tried to setting everything that I can but Json.NET still not send that null string to custom converter. This is my converter code

using System;
using Newtonsoft.Json;
using log4net;

namespace TestProject.Utils.Jsons
{
  public class NullStringConverter : JsonConverter
  {
    private ILog _log = LogManager.GetLogger("Noonswoon.Utils");

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

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        _log.Debug("call NullStringConverter");

        var strValue = value as string;
        if (string.IsNullOrEmpty(strValue))
        {
            _log.Debug("string is null");
            writer.WriteValue(String.Empty);
        }
        else
        {
            _log.DebugFormat("string is not null with value: {0}", strValue);
            writer.WriteValue(strValue);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotSupportedException();
    }

    public override bool CanConvert(Type objectType)
    {
        _log.DebugFormat("NullStringConverter can convert:{0}", objectType);
        return objectType == typeof(string);
    }
  }
}


        [Test]
    public void SerializeProperty_NullString_ConverterToEmptyString()
    {

    var settings = new JsonSerializerSettings
       {
           Formatting = Formatting.Indented,
           ContractResolver = new SpecialContractResolver(),
           NullValueHandling = NullValueHandling.Include,
           DefaultValueHandling = DefaultValueHandling.Include,

       };
        settings.Converters.Add(new NullStringConverter());

        var user = new User()
        {
            FirstName = null,
        };
        var resultString = JsonConvert.SerializeObject(user, settings);
        Console.WriteLine(resultString);

    }

和输出

{
  "Id": 0,
  "Guid": "00000000-0000-0000-0000-000000000000",
  "Height": 0.0,
  "Friends": null,
  "FirstName": null,
  "Credit": 0.0,
  "CreateDate": "0001-01-01T00:00:00+00:00",
  "LastUpdate": "0001-01-01T00:00:00+00:00",
  "DateOfBirth": "0001-01-01T00:00:00",
  "FriendCount": 0,
  "FriendIds": null
}

不按预期返回空字符串,非常感谢

Which not return empty string as I expected , thank you so much

public class Friend
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string FacebookId { get; set; }
}

public class User
{
    public int Id;
    public Guid? Guid { get; set; }
    public float Height { get; set; }
    public List<Friend> Friends { get; set; }
    public string FirstName { get; set; }
    public double? Credit { get; set; }
    public DateTimeOffset CreateDate { get; set; }
    public DateTimeOffset? LastUpdate { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public long FriendCount { get; set; }
    public string[] FriendIds { get; set; }
}






    using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json.Serialization;
using log4net;

namespace TestProject.Utils.Jsons
{
    public class SpecialContractResolver : DefaultContractResolver
    {
        private ILog _log = LogManager.GetLogger("SpecialContractResolver");

        protected override IValueProvider CreateMemberValueProvider(MemberInfo member)
        {
            //if only property
            if (member.MemberType == MemberTypes.Property)
            {
                var pi = (PropertyInfo)member;

                _log.DebugFormat("propertyName: {0} ", pi.Name);

                if (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    return new NullableValueProvider(member, pi.PropertyType.GetGenericArguments().First());

                }

            //if (pi.PropertyType.IsImplementationOf(typeof(ICollection<>)) 
            //    || pi.PropertyType.IsImplementationOf(typeof(ICollection)) 
            //    || pi.PropertyType.IsArray)
            //{
            //       pi.GetValue( 
            //}

            }
            //else if (member.MemberType == MemberTypes.Field)
            //{
            //    var fi = (FieldInfo)member;
            //    if (fi.FieldType.IsGenericType && fi.FieldType.GetGenericTypeDefinition() == typeof(Nullable<>))
            //        return new NullableValueProvider(member, fi.FieldType.GetGenericArguments().First());
            //}

            return base.CreateMemberValueProvider(member);
        }

        protected override System.Collections.Generic.IList<JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization)
        {

            var properties = CreateProperties(type, memberSerialization);
            foreach (var property in properties)
            {
                _log.DebugFormat("property.PropertyName:{0}", property.PropertyName);
            }
            return properties;
        }

    }
}

推荐答案

为使您的转换器执行,您必须使用要自定义的转换器使用JsonConverter属性包装要序列化/反序列化的类:

In order for your converter to execute you have to wrap the class you want to serialize/deserialize with the custom converter with a JsonConverter attribute:

[JsonConverter(typeof(NullStringConverter))]
public class User
{
   public int Id;
   public Guid? Guid { get; set; }
   public float Height { get; set; }
   public List<Friend> Friends { get; set; }
   public string FirstName { get; set; }
   public double? Credit { get; set; }
   public DateTimeOffset CreateDate { get; set; }
   public DateTimeOffset? LastUpdate { get; set; }
   public DateTime? DateOfBirth { get; set; }
   public long FriendCount { get; set; }
   public string[] FriendIds { get; set; }
}

您可以通过在属性中添加DefaultValue属性来实现相同的输出(这是IMO的更简单方法):

You may achieve the same output by adding a DefaultValue attribute to your properties (which is the easier way IMO):

[JsonConverter(typeof(NullStringConverter))]
public class User
{
   [JsonProperty(PropertyName = "id", DefaultValueHandling = DefaultValueHandling.Populate]
   [DefaultValue(string.Empty)] 
   public int Id;
   // The rest of the properties..
}

这篇关于如果该值为null,则Json.NET不会调用我的自定义转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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