Setpoint Extension Point DataContractJsonSerializer

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;

namespace ConsoleApplication1 {
  internal class Program {
    private static void Main(string[] args) {
      var pony = new Pony();
      var serializer = new DataContractJsonSerializer(pony.GetType());
      var example = @"{""Foo"":null}";
      var stream = new MemoryStream(Encoding.UTF8.GetBytes(example.ToCharArray()));
      stream.Position = 0;
      pony = (Pony) serializer.ReadObject(stream);
      // The previous line throws an exception.
    }
  }

  [DataContract]
  public class Pony {
    [DataMember]
    private int Foo { get; set; }
  }
}

Sometimes serialization throws a casting error on Int32s that is set to null. Is there a way to connect to a Json serializer?

+3
source share
4 answers

Foo Int32 System.Nullable<Int32>, ( ), , DataContractJsonSerializer , Json.NET , ( ).

, :

internal class NullableIntConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(int);
    }

    public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
    {
        if (reader.Value == null)
        {
            return default(int);
        }
        return int.Parse(reader.Value.ToString());
    }

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

:

internal class Program
{
    private static void Main(string[] args)
    {
        var serializer = new JsonSerializer();
        serializer.Converters.Add(new NullableIntConverter());
        using (var reader = new StringReader(@"{""Foo"":null}"))
        using (var jsonReader = new JsonTextReader(reader))
        {
            var pony = serializer.Deserialize<Pony>(jsonReader);
            Console.WriteLine(pony.Foo);
        }
    }
}
+2

- int int. , , .

[DataContract]
public class Pony
{
    [DataMember]
    private int? Foo { get; set; }
}
+1

.NET 3.5 ( , ), JavaScriptSerializer. "" ( [DataContract] [DataMember]), . , , :)

.net 3.5 System.Web.Extensions.dll, .NET 4 .

Serializer . , , , , .

:

void Main()
{
    var js = new JavaScriptSerializer();
    js.RegisterConverters(new[] { new PonySerializer() });
    var pony = js.Deserialize<Pony>(@"{""Foo"":""null""}");
    pony.Dump();
}

public class PonySerializer : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get { return new [] { typeof(Pony) }; }
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        if (type == typeof(Pony))
        {
            var pony = new Pony();
            int intValue;

            if (!int.TryParse(dictionary["Foo"] as string, out intValue))
                intValue = -1; // default value. You can throw an exception or log it or do whatever you want here

            pony.Foo = intValue;
            return pony;
        }
        return null;
    }
}

public class Pony
{
    public int Foo { get; set; }
}

P.S. LinqPad, , , Main() ..: P

+1
source

DataContractJsonSerializerhas a DataContractSurrogate property that you can assign. Your surrogate class, which is the implementation IDataContractSurrogate, in GetDeserializedObject can do your custom handling of null values.

0
source

Source: https://habr.com/ru/post/1740305/


All Articles